Firebase Firestore 使用 ID 引用获取数据然后获取引用

Firebase Firestore fetching data with an ID reference then fetching the reference

在为这个问题的答案搜索了几个小时之后,我找到了 1 个 post 相似 :但是我试图复制,但我相信语言语法的差异造成了很难翻译。

在我的应用程序中,允许用户创建 posts,Firsestore 中 post 的结构如下所示:

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

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

问题 通过向我的后端查询 posts,我还如何创建位于其中的用户对象?

这是我期望创建的 post 对象:

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)
            }
    }
}

我解决了!基本上,我们想让第一次获取完成。然后我们遍历每个 post.id 并调用 FetchUser() i 这是我构建的函数 returns Promise<User>

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: [=10=].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: [=11=]) }
}