Простой запрос Firestore не дает мне полные документы в коллекции - PullRequest
0 голосов
/ 06 апреля 2020

Моя модель данных Firestore выглядит следующим образом

Организации / {orgId} / cloudAccounts / {cloudAccountId} / resources / {resourceId}

Я выполняю простую запрос вроде этого

let documents = await db.collection("Organizations")
    .doc("orgIdabc")
    .collection("cloudAccounts")
    .doc("cloudAccountIdabc")
    .collection("resources")
    .get();

console.log("LENGTH: ", documents.docs.length);

Теперь проблема в том, что когда я пытаюсь записать длину документа, он всегда дает мне другую длину. Я поделюсь выводом также.

     LENGTH:  18
  LENGTH:  19
 LENGTH:  19
  LENGTH:  6
  LENGTH:  3
  LENGTH:  19
  LENGTH:  12
  LENGTH:  19
  LENGTH:  19

Теперь фактическая длина равна 19, но, как вы видите, я получаю разные длины. Я не знаю, в чем здесь проблема, любая помощь будет очень признательна.

Обновлено в соответствии с запросом. Я добавляю полный фрагмент кода. Также я узнал, что эта проблема возникает только в Admin SDK, а не в клиентском SDK

const { db } = require("./firestore");
const functions = require("firebase-functions");

exports.runScanOnAllCloudAccounts = functions.https.onRequest((req, res) => {
  runScanOnAllCA();
  return res.status(200);
});

async function runScanOnAllCA() {
  try {
   for (let i = 0; i < 10; i++) {
let documents = await db.collection("Organizations")
    .doc("orgIdabc")
    .collection("cloudAccounts")
    .doc("cloudAccountIdabc")
    .collection("resources")
    .get();

console.log("LENGTH: ", documents.docs.length);
     }
  } catch (err) {
    console.log("err: ", err);
  }
}

Обновление 02 ===========> Я обновил код для использования интенсивного подхода Promise (), как рекомендовано некоторыми пользователями, и я по-прежнему получаю документы различной длины. Я чувствую, что люди здесь упускают суть. Обещания - это просто способ запуска асинхронного кода, мы можем решить эту проблему, используя asyn c await, который уже использовался в предыдущей версии кода. Тем не менее следующий фрагмент кода не решает проблему.

const { db } = require("./firestore");
const functions = require("firebase-functions");

exports.runScanOnAllCloudAccounts = functions.https.onRequest(
  async (req, res) => {
    runScanOnAllCA(res)
      .then(resolve => {
        console.log(resolve);
      })
      .catch(err => {
        console.log(err);
      });
    // return res.status(200);
  }
);

async function runScanOnAllCA(res) {
  return new Promise(async (resolve, reject) => {
    db.collection("Organizations")
      .doc("sumair-hello-world_axtr8")
      .collection("cloudAccounts")
      .doc("4ZQgjt94pvEQTlvxSJ75")
      .collection("resources")
      .get()
      .then(querySnapshot => {
        resolve(querySnapshot.docs.length);
      })
      .catch(err => {
        reject(err);
      });
  });
}

1 Ответ

1 голос
/ 06 апреля 2020

Вы должны использовать Admin SDK для взаимодействия с Firestore из облачной функции.

Во-вторых, известно, что использование циклов await in может привести к "errati c " Результаты. См., Например, https://www.google.com/search?client=firefox-b-d&q=for+and+await

Наконец, обратите внимание, что вы неправильно вызываете свою асинхронную функцию runScanOnAllCA(). Вам следует либо использовать then(), либо настроить облачную функцию async и использовать await, см. Код ниже.

Для использования Admin SDK вы должны адаптировать свой CF следующим образом. :

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

admin.initializeApp();

exports.runScanOnAllCloudAccounts = functions.https.onRequest(async (req, res) => {
    await runScanOnAllCA();   //<--- Note the await here and the async above, since you are calling an async function
    res.status(200);   //<--- No need to use return in an HTTPS Cloud Function, just terminate it with res.redirect(), res.send(), or res.end().
});

async function runScanOnAllCA() {
    try {
        const db = admin.firestore();

        //The loop was removed. Use another way if needed, e.g. Promise.all() or the techniques presented in the links above.

        let documents = await db.collection("Organizations")
                .doc("orgIdabc")
                .collection("cloudAccounts")
                .doc("cloudAccountIdabc")
                .collection("resources")
                .get();

        console.log("LENGTH: ", documents.docs.length);
    } catch (err) {
        console.log("err: ", err);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...