0

In my content view I have a home page with some text that says "Welcome, xxxx" where xxxx is the name fetched from a firebase database. This field can be changed in the settings page that is navigated to via a Navigation Link. When the name is changed and saved the name on the home page only updates when you force shutdown the app. How do I force update the view when you press the back button from settings.

This is how I display the field:

Text("Welcome, \(companyName)")
                        .font(.system(size: 23))
                        .bold()
                        .foregroundColor(Color("background"))
                        .padding(.bottom, 50)

This is how I set a value to companyName:

func SetData() {
    
    var db = Firestore.firestore()
    let user = Auth.auth().currentUser
    let userName = user?.email ?? ""
    let docRef = db.collection("CONTACT").document(userName)
    
    docRef.getDocument { (document, error) in
        if let document = document, document.exists {
            
            //Setting Values
            let data = document.data()
            self.companyName = data?["companyName"] as? String ?? ""
            
        } else {
            print("Document does not exist")
        }
    }
    
}
2
  • onChange(of:perform:)? Commented Aug 11, 2022 at 13:30
  • That won't work as Settings is a different View to the homepage. When the database is updated in the settings page something needs to tell the home page to automatically refresh or update the view. I bypassed this to update everything settings button is pressed via the onAppear method but that stresses the database with many users Commented Aug 11, 2022 at 13:45

2 Answers 2

1

There are several solutions to this, but you haven't provided enough code outlining what you have done to modify the variable companyName. The easiest solution would be to pass companyName as a binding value into the settings.

What I imagine here is that your HomeView is fetching the data on launch. In the settings, a change data request is made, but nothing is done to update the data in the HomeView. By using a binding variable we can ensure that the companyName connects to the source of truth in the HomeView, and so the function modifies the companyName which is precisely the company name on the HomeView vs. modifying potentially the value of companyName.

struct HomeView: View {
    @State var companyName = "Microsoft"
    
    var body: some View {
        NavigationView {
            NavigationLink(destination: SettingsView(companyName: $companyName)) {
                Text("Tap to navigate to Settings")
            }
        }
    }
}

struct SettingsView: View {

@Binding var companyName : String

    var body: some View {
        Button {
            SetData()
        } label: {
            HStack {
                Text("Tap to change!")
                Text("\(companyName)!")
            }
        }
    }
    
    
    func SetData() {
        
        var db = Firestore.firestore()
        let user = Auth.auth().currentUser
        let userName = user?.email ?? ""
        let docRef = db.collection("CONTACT").document(userName)
        
        docRef.getDocument { (document, error) in
            if let document = document, document.exists {
                
                //Setting Values
                let data = document.data()
                self.companyName = data?["companyName"] as? String ?? ""
                
            } else {
                print("Document does not exist")
            }
        }
    }
}

If you have already done this at it doesn't somehow work, another solution is to add an .onAppear modifier to your HomeView.

struct HomeView: View {
    @State var companyName = "Microsoft"

    var body: some View {
        VStack {
            // code ...
        }
        .onAppear {
            fetchData()
        }

    }

    func fetchData() {
        // code that returns companyFetchedName
        self.companyName = companyFetchedName
    }
}

Sign up to request clarification or add additional context in comments.

Comments

0

Modify it on main queue, like

docRef.getDocument { (document, error) in
    if let document = document, document.exists {
        
        //Setting Values
        let data = document.data()
        DispatchQueue.main.async {    // << here !!
          self.companyName = data?["companyName"] as? String ?? ""
        }
        
    } else {
        print("Document does not exist")
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.