#javascript #firebase #google-cloud-firestore
#javascript #firebase #google-cloud-firestore
Вопрос:
У меня есть эта коллекция в моем Firestore:
Collection: Team1
Document: TeamName
Subcollection: Notes
Subcollection: Users
Document: user1 => Field: name: "Anna", uid: "someID"
Document: user2 => Field: name: "John", uid: "someID"
Давайте представим сценарий, в котором существует много коллекций команд с приведенной выше схемой. Как вернуть всю коллекцию Team с помощью JavaScript (чтобы я мог получить доступ, например, к заметкам) на основе поля Name в Document (в вложенной коллекции Users).
Я попробовал это:
var nameRef = db
.collection('Team1')
.doc('TeamName')
.collection('Users')
.where('name', '==', 'Anna')
const getData => ()=> {
nameRef.get().then((snapshot) => {
snapshot.docs.forEach((doc) => {
console.log(doc.data())
})
})
}
Однако приведенный выше код выводит только поля документа в пользовательском документе (имя, uid).
Ответ №1:
Ваш запрос вернет только документы из Users
коллекции. Если вы также хотите отображать данные от пользователя, вам нужно будет загрузить их документ отдельно. Для TeamName
пользователя это было бы:
db
.collection('Team1')
.doc('TeamName')
.get()
Или, в качестве альтернативы, вы можете определить и получить родительский документ для пользователя с помощью:
doc.ref.parent.parent.get()
Если вы хотите выполнить поиск пользователей с именем Anna во всех командах, вы можете использовать запрос группы сбора. Это особый тип запроса, который выполняет поиск по всем коллекциям с определенным именем.
var nameRef = db
.collectionGroup('Users')
.where('name', '==', 'Anna')
const getData => ()=> {
nameRef.get().then((snapshot) => {
snapshot.docs.forEach((doc) => {
console.log(doc.data())
})
})
}
Здесь опять же, это загружает только пользователей, а не их команды. Но вы можете использовать тот же doc.ref.parent.parent.get()
фрагмент, что и раньше, чтобы затем также находить и загружать командный документ для каждого пользователя.
Комментарии:
1. Спасибо, еще одна вещь. Когда я возвращаю doc.ref.parent.parent.get() Я получаю обещание:__proto__: Promise [[PromiseState]]: «выполнено» [[PromiseResult]]: t Df: e {lf: n, f: e, ff: FirebaseAppImpl, df: e, INTERNAL: {…}, …} E : t {путь: n} I_: null Mf: false Of: false kf: n {ключ: t, версия: t, nn: t, Ye: false, hasCommittedMutations: false} существует: (…) идентификатор: (…) метаданные: (…) ссылка: (…) прото : ОбъектПод E_ находятся родители. Как сохранить массив в переменную? Я попробовал реструктуризацию объекта, но это не сработало.
2. Да, как и в случае с вашим исходным
get()
кодом, вам нужно будет добавить еще.then()
одну с функцией для обработки результирующего снимка. В рамках этой функции вы могли бы использоватьsnapshot.docs.forEach
цикл для переноса данных из каждого документа в заранее определенный массив.
Ответ №2:
В дополнение к .data()
методу, полученное doc
также имеет .parent
свойство, которое содержит CollectionReference — в этом случае оно будет ссылаться на вашу Users
коллекцию. У этой коллекции также есть .parent
свойство, которое будет указывать на ваш TeamName
документ. Его родительский элемент будет указывать на вашу Team1
коллекцию.
Используя эти родительские свойства документов и коллекций, вы можете проложить свой путь «вверх» по дереву до своей коллекции Team, из которой вы можете извлекать ее документы.