просмотреть документы в коллекции, чтобы получить поля

У меня есть коллекция под названием пользователи в firebase firestore. Каждый документ в коллекции users - это пользователь, зарегистрированный в приложении. В каждом документе есть поле token_ids. Как я могу просмотреть все документы, чтобы получить значения в поле token_ids. Для этого я использую облачные функции firebase. Вот фрагмент кода, который я пытался использовать, но он не сработал:

const functions = require('firebase-functions');
const admin = require ('firebase-admin');
admin.initializeApp();

  //fetch all token ids of users

  const tokenReference = admin.firestore().collection("users");

  const tokenSnapshot  = await tokenReference.get();

  tokenSnapshot.forEach((doc) =>{

    console.log("Token ids are:" + doc.data().token_id);


  });

  });


person James Gitonga    schedule 30.06.2020    source источник
comment
Я не вижу полного кода, который вы пробовали.   -  person Ashish    schedule 30.06.2020
comment
Не могли бы вы уточнить, как вы считаете, что не работает, каково ваше ожидаемое поведение, каково ваше текущее поведение и как вы запускаете свой скрипт?   -  person Prashin Jeevaganth    schedule 30.06.2020


Ответы (3)


Поскольку операции Firestore являются асинхронными, в идеале вы должны заключить свой код в блок async-await.

Например:

async function fetchAllTTokenIds() {

  const tokenReference = admin.firestore().collection("users");
  
  const tokenSnapshot  = await tokenReference.get();
  const results = [];
  // Recommendation: use for-of loops, if you intend to execute asynchronous operations in a loop.
  for(const doc of tokenSnapShot) {
    results.push(doc.data().token_id);
  }
  const tokenIds = await Promise.all(results);
}

Таким образом, вся переменная tokenIds будет заполнена массивом tokenIds.

В качестве альтернативы вы также можете выполнять все асинхронные вызовы параллельно, поскольку они не зависят друг от друга, используя Promise.all (Справочник)

async function fetchAllTTokenIds() {

  const tokenReference = admin.firestore().collection("users");
  
  const tokenSnapshot  = await tokenReference.get();

  const tokenIds = await Promise.all(tokenSnapShot.map(doc => {
    return doc.data()
      .then(data => (data.token_id)) 
  }))

В этом случае переменная tokenIds будет содержать массив всех tokenIds.

person Dhruv Shah    schedule 30.06.2020
comment
Я попробовал первый ответ. Это дало следующую ошибку: Неожиданный await внутри цикла - person James Gitonga; 30.06.2020
comment
Это похоже на lint ошибку. Однако я обновил свой ответ и удалил ожидание из цикла. - person Dhruv Shah; 30.06.2020
comment
Второе решение дало следующую ошибку в журналах облачных функций: TypeError: tokenSnapshot.map не является функцией - person James Gitonga; 30.06.2020
comment
после обновления я запустил код, но он выдал эту ошибку TypeError: tokenSnapshot не повторяется в журналах облачного хранилища. - person James Gitonga; 01.07.2020

Мне потребовалось время, но я наконец нашел решение. Вот. Это первое решение, данное Дхрувом Шахом, но с небольшими изменениями:

async function fetchAllTTokenIds() {

  const tokenReference = admin.firestore().collection("users");
  
  const tokenSnapshot  = await tokenReference.get();
  const results = [];
  tokenSnapshot.forEach(doc => {

    results.push(doc.data().token_id);

  });

  const tokenIds = await Promise.all(results);

  return console.log("Here =>" +tokenIds);


}


person James Gitonga    schedule 01.07.2020
comment
Если вы нашли решение, примите свой собственный ответ. - person Kevin Quinzel; 02.07.2020

Как будет структурирован фрагмент кода, зависит от того, используете ли вы Firebase Admin SDK, будь то скрипт, запущенный на вашем локальном компьютере, или httpsCallable, вызываемый клиентским приложением. Для первого случая это записывается так:

В вашем скрипте file.js после инициализации приложения напишите следующий код.

exports.test_f = async function() {
  try {

    const tokenReference = admin.firestore().collection("users");

    const tokenSnapshot  = await tokenReference.get();

    tokenSnapshot.forEach((doc) =>{

      console.log("Token ids are:" + doc.data().token_id);


    });
  } catch (error) {
    console.log(error);
  }
}

exports.test_f();

Запустите этот сценарий в командной строке с помощью команды node file.js, которая распечатает предоставленный вывод.

person Aqil    schedule 30.06.2020