swift - Firebase Firestore 使用 ID 引用获取数据,然后获取引用
问题描述
在为这个问题的答案搜索了几个小时后,我在这里找到了 1 篇类似的帖子:但是我试图复制,但我相信语言语法的差异使得翻译变得非常困难。
在我的应用程序中,允许用户发帖,Firsestore 中的帖子结构如下所示:
creator
是也存在于数据库中的用户的用户 ID 。
当我的结构符合 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)
}
}
}
解决方案
我解决了!基本上,我们想让第一次 fetch 完成。然后我们遍历每个 post.id 并调用FetchUser()
i ,这是我构建的返回函数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)
}
}
}
这里是调用点:
public func fetch(for schoolId: String) -> Promise<[Post]> {
return fetchTopLevelPost(for: schoolId)
.then { self.fetchPostUser(for: $0) }
}
推荐阅读
- java - STOMP 目标 url 与端点 url
- javascript - 获取每个列表元素的最后 3 个字符并使用 Javascript 将其更改为 #
- cas - ENDECA - 爬网在baseline_update 中返回错误
- docker - 远程访问页面时出现“无法启动‘npm’”错误消息
- c++ - 成员函数的 pragma GCC 毒药语法
- assembly - 在汇编语言 8086 中交换字符串中的字母
- android - 如何在 kotlin 中设置定时闹钟?
- angular - 如何在 Web 主机服务器中运行节点邮件程序
- rest - 在执行 $.ajax() 的函数成功或错误时,sharepoint 2013 中没有执行。我正在使用 rest api
- uinavigationcontroller - 快速使导航栏和标签栏透明