Я пытаюсь получить сообщения из списка учетных записей, на которые подписан пользователь, но не уверен, как это сделать? Я реализовал ту же структуру из этого ответ на переполнение стека, так как считаю ее разумной для того, что я пытался создать (см. Ниже).
Firestore-root
|
--- users (collection)
| |
| --- uid (documents)
| |
| --- name: "User Name"
| |
| --- email: "[email protected]"
|
--- following (collection)
| |
| --- uid (document)
| |
| --- userFollowing (collection)
| |
| --- uid (documents)
| |
| --- uid (documents)
|
--- posts (collection)
|
--- uid (documents)
|
--- userPosts (collection)
|
--- postId (documents)
| |
| --- title: "Post Title"
| |
| --- date: September 03, 2018 at 6:16:58 PM UTC+3
|
--- postId (documents)
|
--- title: "Post Title"
|
--- date: September 03, 2018 at 6:16:58 PM UTC+3
Однако я изо всех сил пытаюсь понять, как лучше всего получить список сообщений, в которых UID документа совпадает с тем, на который подписан пользователь.
Я попытался получить всех подписчиков пользователей, а затем для каждого документа перебрать его с помощью другого метода get, но не нашел успешного решения. Пример этого кода можно увидеть ниже:
var userFollowingList = [User]()
db.collection("Following").document(currentUserUID).collection("userFollowing")
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
completion(false)
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
userFollowingList = querySnapshot!.documents.compactMap { querySnapshot -> User? in
return try? querySnapshot.data(as: User.self)
}
}
for user in userFollowingList {
db.collection("Posts")
.getDocuments() { (tripQuerySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
completion(false)
} else {
for document in tripQuerySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.followingTrips = querySnapshot!.documents.compactMap { querySnapshot -> Trip? in
return try? querySnapshot.data(as: Trip.self)
}
}
}
}
}
}
Какой самый эффективный способ добиться этого? Спасибо.
ОБНОВЛЕНИЕ 30/03/2020:
В итоге я перебирал каждый идентификатор пользователя в следующем списке и возвращал все сообщения для пользователей, но я все еще не уверен, что это лучший способ. См. Пример ниже:
let userFollowingIDs = ["01","02","03"]
for id in userFollowingIDs {
db.collection("Trips").document(id).collection("userPosts")
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
completion(false)
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.followingTripsList = querySnapshot!.documents.compactMap { querySnapshot -> Trip? in
return try? querySnapshot.data(as: Trip.self)
}
}
completion(true)
}
}
}
Привет, Джей. В итоге я выбрал тот подход, который вы отметили, и обновил свой пост, чтобы показать последний код. Извините за непонятность, вы правы, и это то, что я хотел сделать, я просто надеялся, что есть лучший способ, поэтому мне не нужно было сначала получать коллекцию usersFollowing. К сожалению, искусство ascii не мое, лол, я скопировал пример из связанного вопроса о переполнении стека.





Я думаю, что это можно сделать проще. Конечно, у меня нет подробностей всей системы, однако, глядя на эту конкретную проблему, я бы добавил в каждый документ userPosts новое поле followedBy. Это поле будет массивом, в котором будут храниться все следующие идентификаторы пользователей сообщения (uid).
Теперь проверка, следит ли за конкретными сообщениями конкретный пользователь, может быть выполнена путем проверки, содержит ли этот массив followedBy этот идентификатор пользователя. Тогда можно будет использовать две функции Firestore: collectionGroup и arrayContains filter.
Тогда получить список сообщений, за которыми следует конкретный пользователь, будет очень просто, вот так:
db.collectionGroup("userPosts")
.whereField("followedBy", arrayContains: uid)
.getDocuments() { (snapshot, error) in
// ...
Никаких циклов и меньше документов из Firestore. Это должно быть более эффективным с точки зрения затрат на использование.
Спасибо, vitooh, я раньше не думал об этом подходе, но определенно имеет больше смысла. Я реализовал это сейчас и работает нормально. Для всех, кто может это прочитать, вам нужно будет настроить индексы в firebase, но при первом запуске кода вам будет показана ошибка, которая дает вам ссылку для использования для создания нужного индекса.
Добро пожаловать, и да. Правда насчет индексов можно это проверить вопрос
Вопрос и проблема немного неясны. Есть узел следующий, в котором есть документы с идентификатором пользователя в качестве ключа для каждого. В нем находится список uid пользователей, за которыми они следят. Итак, если вы загрузите эту коллекцию userFollowing, вы узнаете все uid, за которыми они следуют. Есть коллекция aсообщения, организованная uid. Если вы перебираете каждый загруженный uid, вы можете загрузить соответствующие сообщения пользователей из коллекции сообщений. Есть что-то еще? Что вы делаете со всеми этими данными сразу? +1 для вашего ascii art, кстати, - сделал структуру Firestore действительно понятной.