Я пришел из MongoDB и изо всех сил пытаюсь понять getDoc()
и getDocs()
.
Я правильно это понимаю?
Принимает ли getDoc()
в качестве параметра только идентификатор документа? Или я могу сделать запрос?
В документации я могу найти только такой код:
const docRef = doc(db, "collection", "11aa22bb33ccc");
const myDoc = await getDoc(docRef);
Но что, если я не знаю идентификатор или хочу выполнить поиск по другому параметру, например по полю author
? Правильно ли, что я не смогу сделать это с getDoc()
?
С MongoDB я могу db.collection.findOne({ author: "jones" })
.
Могу ли я не сделать это с Firestore?
Итак, если я хочу использовать запрос, всегда ли мне нужно использовать getDocs()
?
Если это так, я знаю, что могу использовать limit(1)
, но обработка ответа для получения этого одного документа кажется не такой гладкой, как в mongodb.
Я попробовал это:
const documents = collection(firebaseDb, 'documents');
const query = query(documents, where('author', '==', 'jones'));
const authorDocs = await getDocs(query, limit(1));
console.info(authorDocs[0].data());
И у меня появилась ошибка: Cannot read properties of undefined (reading 'data')
Поэтому я думаю, что мне нужно использовать forEach
, вот так:
authorDocs.forEach(doc => console.info( doc.data() ));
Но только для одного документа? Это кажется странным. Есть ли способ лучше?
привет @SandeepVokkareni, спасибо за ответ, однако это та же самая документация, которую я просматривал. Там, где написано docRef = doc(db, "cities", "SF")
, SF
— это идентификатор документа, верно?
Принимает ли getDoc() только идентификатор документа в качестве параметра?
Нет, getDoc()
требует аргумента типа «ссылка на документ», указывающего на документ, существующий в коллекции Firestore.
Но что, если я не знаю идентификатор или хочу выполнить поиск по другому параметру, например по полю «автор»?
Тогда вам действительно нужно использовать запрос, который выглядит следующим образом:
const queryByAuthor = query(collection(db, "documents"), where("author", "= = ", "jones"));
Правильно ли, что я не смогу сделать это с помощью getDoc()?
Да, getDoc()
используется для чтения одного документа, а не нескольких документов, возвращаемых запросом. Если вы хотите прочитать все документы, вам действительно нужно использовать getDocs() и перебирать результаты:
const querySnapshot = await getDocs(queryByAuthor);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.info(doc.id, " => ", doc.data());
});
Если вы хотите прочитать только первый документ, вам следует прочитать документ с индексом 0, querySnapshot[0]
:
const querySnapshot = await getDocs(queryByAuthor);
if (querySnapshot.docs.length > 0) {
const doc = querySnapshot.docs[0];
console.info('Document data:', doc.data());
}
Кроме того, всегда старайтесь не использовать неопределенные объекты для создания ссылок или запросов Firestore.
вы ответили no
на мой вопрос о getDoc()
принятии только удостоверения личности. Но в документации есть такой пример docRef = doc(db, "cities", "SF")
. SF
это идентификатор документа, верно?
Я сказал нет, в вашем контексте, где вы используете ссылку на документ. Но действительно getDoc()
может принять в качестве аргумента идентификатор документа.
ок, спасибо за разъяснения. Могу ли я получить немного больше разъяснений, пожалуйста. И getDoc()
не может принять запрос в качестве аргумента, верно? Только идентификатор документа? Вы сказали, что он «может принять...», так что я просто проверяю дважды. Спасибо.
Да, getDoc(
) не может принять запрос в качестве аргумента, только getDocs()
может.
Алекс, еще один вопрос. Я заметил, что вы использовали .docs[0]
, попробовал, и это сработало. Почему мы можем запустить forEach()
с помощью querySnapshot
, но это не работает: querySnapshot[0]
?
forEach
уже существует в первом фрагменте кода. Вам нужно запросить querySnapshot
не первый документ внутри результата, верно?
Взгляните на эту Документацию.