Firebase Firestore提取具有ID引用的数据,然后获取引用

时间:2020-08-29 21:27:36

标签: swift firebase google-cloud-firestore promisekit

在搜索了几个小时的答案之后,我发现有1篇与here类似的帖子:但是我尝试进行复制,但是我相信语言语法上的差异使得翻译非常困难。

在我的应用程序中,允许用户发布帖子,Firsestore中帖子的结构如下:

enter image description here

creator是也位于数据库中的用户的userId。

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

问题 通过查询后端的帖子,我还如何创建生活在其中的用户对象?

这是我希望创建的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?
}

我想从返回的appUser字段中创建creator。我应该构建内容然后使用某种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)
            }
    }
}

1 个答案:

答案 0 :(得分:0)

我解决了!基本上,我们希望完成第一次提取。然后,我们遍历每个post.id并调用dplyr::mutate(roll = zoo::rollapplyr(deaths, width = 2, FUN = mean, partial = TRUE)) i,这是我构建的返回FetchUser()

的函数
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: $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)
        }
    }
}