Редактировать: Этот вопрос предназначен для FireStore, поэтому этот ответ включает в себя ответ базы данных Firebase, а также ответ Firestore и затем полный ответ Firestore.
База данных Firebase Вопрос состоит в том, какпереберите узел сообщений и найдите пользователя, связанного с каждым сообщением, с помощью uid пользователя.
Вот, пожалуйста,
С учетом структуры
posts
post_0
post: "some post"
uid: "uid_1"
post_1
post: "another post"
uid: "uid_1"
users
uid_0
Name: "Henry"
uid_1
Name: "Josh"
и кода дляпереберите все сообщения и напечатайте сообщение и имя пользователя, который его создал:
let postsRef = self.ref.child("posts")
let usersRef = self.ref.child("users")
postsRef.observeSingleEvent(of: .value, with: { snapshot in
guard let allPostsSnapshot = snapshot.children.allObjects as? [DataSnapshot] else {return}
for childPostSnap in allPostsSnapshot {
let uid = childPostSnap.childSnapshot(forPath: "uid").value as! String
let post = childPostSnap.childSnapshot(forPath: "post").value as! String
let thisUserRef = usersRef.child(uid)
thisUserRef.observeSingleEvent(of: .value, with: { userSnap in
let userName = userSnap.childSnapshot(forPath: "Name").value as! String
print(post, userName)
})
}
})
и вывод
some post Josh
another post Josh
FireStore
Я разбил это на две функции: одну для чтения документов постов и одну для чтения имени пользователя для каждого поста.Я просто печатаю строки в этом ответе, но это показывает, как получить доступ к данным FireStore, чтобы вы могли экстраполировать их оттуда.
func readPosts() {
self.db.collection("posts").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let uid = document.get("uid") as! String
let post = document.get("post") as! String
self.printUserAndPost(withUid: uid, andPost: post)
}
}
}
}
func printUserAndPost(withUid: String, andPost: String) {
let docRef = self.db.collection("users").document(withUid)
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let name = document.get("name") as! String
print(name, andPost)
} else {
print("doument does not exist")
}
}
}
и вывод
Josh Some Post
Josh Another post
Другое редактирование:
Основываясь на комментариях к исходному постеру, они хотели бы добавить объект публикации и объект пользователя и массив в виде кортежа.Поскольку у нас нет этой информации в исходном посте, я разработал довольно полное решение - см. Ниже.Второй вопрос: почему массив кортежей печатает счет 0 в исходной записи?Причина в том, что Firebase / Firestore является асинхронным и в исходном вопросе эта строка
print(joinedPosts.count)
вызывается до , когда пользователи заполняются с
API.User.getUser(userID: post.ownerID!
так что массив на самом деле равен 0, когда эта функция вызывается, и> 0 в какой-то момент времени впоследствии.Мой ответ включает в себя обработку этого.
class PostClass {
var post_id = ""
var post_text = ""
var owner_id = ""
init(ownerId: String, postId: String, postText: String) {
self.owner_id = ownerId
self.post_id = postId
self.post_text = postText
}
}
class UserClass {
var user_id = ""
var user_name = ""
init(userId: String, userName: String) {
self.user_id = userId
self.user_name = userName
}
}
var joinedPosts = [(aUser: UserClass, aPost: PostClass)]()
var docCount = 0
func readPosts() {
self.db.collection("posts").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
self.docCount = querySnapshot!.documents.count
for document in querySnapshot!.documents {
let postId = document.documentID
let uid = document.get("uid") as! String
let postText = document.get("post") as! String
let post = PostClass(ownerId: uid, postId: postId, postText: postText)
self.addUserAndPostTupleToArray(withUid: uid, andPost: post)
}
}
}
}
func addUserAndPostTupleToArray(withUid: String, andPost: PostClass) {
let docRef = self.db.collection("users").document(withUid)
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let name = document.get("name") as! String
let user = UserClass(userId: withUid, userName: name)
let myTuple = (aUser: user, aPost: andPost)
self.joinedPosts.append(myTuple)
if self.joinedPosts.count == self.docCount {
print("total posts: \(self.joinedPosts.count)")
for myTuple in self.joinedPosts {
let name = myTuple.aUser.user_name
let postText = myTuple.aPost.post_text
print("User \(name) said \(postText)")
}
}
} else {
print("doument does not exist")
}
}
}
и вывод
total posts: 2
User Josh said Some Post
User Josh said Another post