繁体   English   中英

使用 SwiftUI 在 Firestore 中匹配 collections

[英]Matching collections in Firestore using SwiftUI

我正在尝试通过使用下面的代码匹配 collections 从 Firestore 获取文档。 我正在从集合(“用户”)中获取文档,以防将来有人更新他们的信息,新信息只会上传到集合(“用户”)而不是集合(“客户”)。

struct NewFriend: Identifiable, Hashable, Decodable {
    @DocumentID var id: String?
    var name: String
    var uid: String
}

struct NewProspect: Identifiable, Hashable, Decodable {
    @DocumentID var id: String?
    var name: String
    var uid: String
}

class AuthViewModel: ObservableObject {

@Published var userName = ""
@Published var friendName1 = "FriendName1"
@Published var friendName2 = "FriendName2"
@Published var friendUid1 = "friendUid1"
@Published var friendUid2 = "friendUid2"
@Published var matchingUid = ""
let friends = [NewFriend]()
let clients = [NewProspect]()

func uploadInfo() {
        guard let uid = FireBaseManager.shared.auth.currentUser?.uid else { return }
        let data: [String: Any] = [
            "name": self.userName,
            "uid": uid
        ]

        FireBaseManager.shared.firestore.collection("users").document(uid).setData(data) { error in
            if let error = error {
                print("DEBUG: Failed to store user info with error: \(error.localizedDescription)")
                return
            }
        }
    }
}

func addFriend() {
        guard let uid = FireBaseManager.shared.auth.currentUser?.uid else { return }
        let data: [String: Any] = [
            "name": self.friendName1,
            "uid": self.friendUid1
        ]

        FireBaseManager.shared.firestore.collection("users").document(uid).collections("clients").document(self.friendUid1).setData(data) { error in
            if let error = error {
                print("DEBUG: Failed to store user info with error: \(error.localizedDescription)")
                return
            }
        }

func addFriend2() {
        guard let uid = FireBaseManager.shared.auth.currentUser?.uid else { return }
        let data: [String: Any] = [
            "name": self.friendName2,
            "uid": self.friendUid2
        ]

        FireBaseManager.shared.firestore.collection("users").document(uid).collections("clients").document(self.friendUid2).setData(data) { error in
            if let error = error {
                print("DEBUG: Failed to store user info with error: \(error.localizedDescription)")
                return
            }
        }

func fetchFriends() {
        guard let uid = FireBaseManager.shared.auth.currentUser?.uid else { return }
            FireBaseManager.shared.firestore.collection("users").document(uid).collection("clients").getDocuments { snapshot, _ in
                
                guard let documents = snapshot?.documents else { return }
                self.friends = documents.compactMap({ try? $0.data(as: NewFriend.self) })
                
                for i in 0 ..< self.friends.count {
                    self.matchingUid = self.friend[i].uid
                    print("print1: \(self.matchingUid)")

                    FireBaseManager.shared.firestore.collection("users")
                        .whereField("uid", isEqualTo: self.friendUid)
                        .getDocuments { snapshot, _ in
                            guard let documents = snapshot?.documents else { return }
                            self.clients = documents.compactMap({ try? $0.data(as: NewProspect.self) })
                            print("print2: \(self.matchingUid)")
                        }
                }
            }
    }
}

struct ListView: View {

@ObservedObject var viewModel = AuthViewModel()

     var body: some View {

          List {
                       ForEach(viewModel.clients) { client in
                           Text(client.name)
                                .padding()
                       }
               }
               .onAppear {
                   viewModel.fetchFriends()
               }
     }
}

我可以在 print1 中打印两个朋友的 uid,但是当涉及到 print2 时,只打印了一个 uid,并且列表只显示了两个朋友中的一个。 知道为什么会这样吗? 或者有没有更好的方法让这个 function 工作?

当您在 print2 之前获取用户时,您正在使用 where 子句进行获取。

self.db.collection("users")
    // This WHERE condition causes that only one friend will be found
    .whereField("uid", isEqualTo: self.friendUid1)
    .getDocuments { snapshot, _ in
        guard let documents = snapshot?.documents else { return }
        self.clients = documents.compactMap({ try? $0.data(as: NewProspect.self) })
        print("print2: \(self.matchingUid)")
    }

您示例中的那个( self.friendUid )不是您的 AuthViewModel 的一部分,我假设您的意思是.whereField("uid", isEqualTo: self.friendUid1)

无论如何,那个 where 子句将您的结果限制为一个朋友(在这种情况下,只有friendUid1的朋友。

也许你可以使用.whereField("uid", in: [self.friendUid1, self.friendUid2])代替:

self.db.collection("users")
    // In this case the WHERE condition cares about both friends
    .whereField("uid", in: [self.friendUid1, self.friendUid2])
    .getDocuments { snapshot, _ in
        guard let documents = snapshot?.documents else { return }
        self.clients = documents.compactMap({ try? $0.data(as: NewProspect.self) })
        print("print2: \(self.matchingUid)")
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM