检索和更新存储在 Firestore 中的数据

孟菲斯孟

我正在 iOS 上开发移动应用程序,需要在用户单击按钮时跟踪一些数据。但是,当我尝试根据官方文档获取数据时,什么也没有显示这是我的片段:

import SwiftUI
import FirebaseStorage
import FirebaseCore
import FirebaseFirestore

struct Station_View: View {
    @State private var showingAlert = false
    var ref: Firestore!
    
    var station_ : station
    var food : [food] = []
    var body: some View {
        VStack(alignment: .leading, spacing: 10, content: {
            VStack {
                ForEach(station_.menu_items, id: \.self) { i in
                    Divider()
                    .frame(width: 400, height: 1)
                    .background(Color("Black"))
                    .padding(.vertical,0)
                    HStack {
                        VStack (alignment: .leading) {
                            Text(i.name + ", " + i.calories + "cal, protein: " + i.protein)
                            .font(.headline)
                            .foregroundColor(Color("Black"))
                                
                        }.padding(.leading, 8)
                        Spacer()
                        if (Int(i.protein)! > 10) {
                            Button(action: {
//                                print("Button action")
////////// I retrieved data here //////////////////                      
                                let docRef = ref?.collection("users").document("7lqIqxc7SGPrbRhhQWZ0rdNuKnb2")
                                docRef?.getDocument { (document, error) in
                                    if let document = document, document.exists {
                                        let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
                                        print("Document data: \(dataDescription)")
                                    } else {
                                        print("Document does not exist")
                                    }
                                }
////////// I retrieved data here //////////////////  
                                self.showingAlert = true
                            }) {
                                HStack {
                                    Image(systemName: "p.circle")
                                    Text("+50xp")
                                }.padding(10.0)
                                .overlay(
                                    RoundedRectangle(cornerRadius: 6.0)
                                        .stroke(lineWidth: 2.0)
                                )
                            }
                            .alert(isPresented: $showingAlert) {
                            () -> Alert in
                            Alert(title: Text("Congratulations!"), message: Text("You had a protein meal, XP+50!"), dismissButton: .default(Text("OK")))
                                }
                        }
                        if (i.is_vegan) {
                            Button(action: {
//                                print("Button action")
////////// I retrieved data here //////////////////  
                                let docRef = ref?.collection("users").document("7lqIqxc7SGPrbRhhQWZ0rdNuKnb2")
                                docRef?.getDocument { (document, error) in
                                    if let document = document, document.exists {
                                        let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
                                        print("Document data: \(dataDescription)")
                                    } else {
                                        print("Document does not exist")
                                    }
                                }
////////// I retrieved data here //////////////////  
                                self.showingAlert = true
                            }) {
                                HStack {
                                    Image(systemName: "leaf")
                                    Text("+50xp")
                                }.padding(10.0)
                                .overlay(
                                    RoundedRectangle(cornerRadius: 6.0)
                                        .stroke(lineWidth: 2.0)
                                )
                            }
                            .alert(isPresented: $showingAlert) {
                                () -> Alert in
                                Alert(title: Text("Congratulations!"), message: Text("You had a vegan meal, XP+50!"), dismissButton: .default(Text("OK")))
                                    }
                        }
                            
                       
                    }
                    .padding(.init(top: 12, leading: 0, bottom: 12, trailing: 0))
                    
                    
                    
                }
            }
        } )
    }
}

我该怎么做才能让它成真?我希望只更新一个键值对,而其他键值对在收集数据时保持不变。

xTwisteDx

首先,在使用 SwiftUI 时,您应该始终使用 ViewModel。起初这是一个奇怪的过渡,但它会让你的代码更容易理解和跟踪。这是基本结构。

查看模型

class YourViewModel: ObservableObject {
    @Published var isTrue = false

    func isValueTrue(){
         print(isTrue.description)
    }
}

请注意,这里发生了一些事情ObservableObject@Published本质上这意味着YourViewModel可以使用已发布的属性或可以绑定到视图的属性来观察对象要在视图中使用它,您可以这样做。

查看

struct YourView: View {
    //This is your ViewModel reference.
    //Use is to bind all your details to the view with
    //something like yourViewModel.firstName or $yourViewModel.firstName
    @observedObject var yourViewModel = YourViewModel()
    var body: some View {
        Button("Change Bool") {
             yourViewModel.isTrue.toggle()
             yourViewModel.isValueTrue()
        }
    }
}

这是 MVVM 模式的基本结构,将为您节省大量的视图空间,使其更易于阅读和维护。通常,您将有一个单独的.swift文件用于ViewViewModel尽量不要将它们组合起来,并尽可能多地抽象。

要回答最终的问题,您如何从 Firebase 检索数据并更新相同的数据?那么,答案如下,我将演示如何使用中的功能和属性ViewModel,你可以Bind对你的意见对其进行更新。

获取 Firebase 数据

//These properties are a part of the VIEWMODEL and can be bound to the view
//Using yourViewModel.someProperty
@Published var firstName = ""
@Published var lastName = ""
@Published var email = ""

func fetchFirebaseData() {
            guard let uid = Auth.auth().currentUser?.uid else {
            print("Handle Error")
            return
        }

        //Create Database Reference
        let db = Firestore.firestore()

        //Reference the collection and document. In this example
        //I'm accessing users/someUserId
        let fsUserProfile = db.collection("users").document(uid)
        
        //Request the document 
        fsUserProfile.getDocument { (snapshot, err) in
            if err != nil { return }
            self.fetchImageFromURL(url: URL(string: snapshot?.get("profile_image_url") as? String ?? "")!)
            self.firstName = snapshot?.get("first_name") as? String ?? ""
            self.lastName = snapshot?.get("last_name") as? String ?? ""
            self.email = snapshot?.get("email") as? String ?? ""
        }
}

更新 Firebase 数据

这是更新 Firebase 数据的简单方法。这是通过传递一个带有键的字典来处理的,键是字段和与之关联的值。警告:不要使用setData(...)它会清除你在那里的所有其他东西。setData(...)对于首次创建数据很有用,例如注册帐户、创建新条目等。

func updateFirebaseData(firstName: String) {
    if let user = Auth.auth().currentUser {
         let db = Firestore.firestore()   
         db.collection("users").document(user.uid).updateData(["first_name": firstName])
        }
    }

用法

struct YourView: View {
    @observedObject var yourViewModel = YourViewModel()
    
    var body: some View {
        
        VStack {
            
            //Fetching Example
            VStack {
                Button("Fetch Data") {
                    yourViewModel.fetchFirebaseData()
                }
                Text(yourViewModel.firstName)
            }
            
            //Setting Example
            VStack {
                Button("Update Data") {
                    //You could have this "John" value, a property
                    //of your ViewModel as well, or a text input, or whatever
                    //you want.
                    yourViewModel.updateFirebaseData(firstName: "John")
                }
            }
        }
    }
}

请注意,在 SwiftUI 中工作时 MVVM 结构是多么干净,一旦你这样做了几天,它就会成为第二天性。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章