【问题标题】:Firebase Firestore fetching data with an ID reference then fetching the referenceFirebase Firestore 使用 ID 引用获取数据,然后获取引用
【发布时间】:2020-08-29 21:27:36
【问题描述】:

在为这个问题的答案搜索了几个小时后,我发现了 1 个类似 here 的帖子:但是我尝试复制,但我相信语言语法的差异使其很难翻译。

在我的应用程序中,用户可以发帖,Firsestore 中的帖子结构如下所示:

creator 是同样存在于数据库中的用户的用户 ID。

当我的结构符合 Codable 并且它们映射 1 到 1 时,我知道如何从 Firestore 获取内容,但我没有经历过在初始获取后必须获取嵌套数据。

问题 通过在我的后端查询帖子,我怎样才能创建驻留在里面的用户对象?

这是我希望创建的帖子对象:

import FirebaseFirestoreSwift

public struct Post: Codable {
    /// The school id
    @DocumentID var id: String?
    /// The name of the school
    public let content: String
    /// The user who made the post
    public var creator: AppUser?
}

我想从返回的creator 字段创建appUser。我应该构建内容然后有某种promise.then 来获取用户吗?或者我可以同时做这两个吗?

这是我认为我应该做的事情

    public func fetch(for schoolId: String) -> Promise<[Post]> {
    return Promise { resolver in
        fireStore
            .collection("schools").document(schoolId)
            .collection("posts").getDocuments { (querySnapshot, err) in
                guard let documents = querySnapshot?.documents else {
                  resolver.reject(Errors.firebaseError)
                  return
                }
                
                let posts = documents.compactMap { queryDocumentSnapshot -> Post? in
                  return try? queryDocumentSnapshot.data(as: Post.self)
                }
                
                let postsWithUser: [Post] = posts.map { post in
                    //Fetch User and return an updated struct
                }
                resolver.fulfill(postsWithUser)
            }
    }
}

【问题讨论】:

    标签: swift firebase google-cloud-firestore promisekit


    【解决方案1】:

    我解决了!基本上,我们想让第一次 fetch 完成。然后我们遍历每个 post.id 并调用 FetchUser() i 这是我构建的一个函数,它返回 Promise&lt;User&gt;

    func fetchTopLevelPost(for schoolId: String) -> Promise<[Post]> {
        return Promise { resolver in
        fireStore
            .collection("schools").document(schoolId)
            .collection("posts").getDocuments { (querySnapshot, err) in
                guard let documents = querySnapshot?.documents else {
                  resolver.reject(Errors.firebaseError)
                  return
                }
    
                let posts = documents.compactMap { queryDocumentSnapshot -> Post? in
                  return try? queryDocumentSnapshot.data(as: Post.self)
                }
                resolver.fulfill(posts)
            }
        }
    }
    
    func fetchPostUser(for posts: [Post]) -> Promise<[Post]> {
        let allPromise = posts.map{ FetchUser().fetch(for: $0.creatorId) }
        return Promise { resolver in
            when(fulfilled: allPromise).done { users in
                let completePost = zip(users, posts).map(post.init(completeData:))
                resolver.fulfill(completePost)
            }
            .catch { error in
                resolver.reject(Errors.firebaseError)
            }
        }
    }
    

    这里是调用点:

    public func fetch(for schoolId: String) -> Promise<[Post]> {
        return fetchTopLevelPost(for: schoolId)
            .then { self.fetchPostUser(for: $0) }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-12
      • 2018-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多