Как я могу получить доступ к данным Firestore из облачной функции Google?

# #javascript #firebase #google-cloud-firestore #google-cloud-functions

Вопрос:

Это мой первый раз, когда я использую облачные функции. Я пытаюсь сделать простой вызов, чтобы получить доступ ко всем предприятиям, хранящимся в моей коллекции Firestore, но когда я пытаюсь зарегистрировать результаты, я всегда получаю пустой массив.

Все вещи в/ Firebase/хранилище настроены правильно, имя коллекции указано правильно, и подтвержден доступ к базе данных путем входа в БД. Есть ли что-то явно неправильное в моем коде здесь? Спасибо!

 // The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
admin.initializeApp();


exports.updateBusinessData = functions.https.onRequest((request, response) => {
  const db = admin.firestore()

  const businessesReference = db.collection('businesses')
  var businesses = []

  const getBusinesses = async () => {
    const businessData = await businessesReference.get()

    businesses = [...businessData.docs.map(doc => ({...doc.data()}))]

    for (let business in businesses) {
      console.log(business)
    }

    response.send("Businesses Updated")

  }

  getBusinesses()
});
 

Ответ №1:

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

 exports.updateBusinessData = functions.https.onRequest((request, response) => {
  const db = admin.firestore();

  const businessesReference = db.collection("businesses");
  const businesses = [];

  const getBusinesses = async () => {
    const businessData = await businessesReference.get();

    businessData.forEach((item)=> {
      businesses.push({
        id: item.id,
        ...item.data(),
      });
    });

    // used for of instead of in
    for (const business of businesses) {
      console.log(business);
    }

    response.send(businesses);
  };
  
  getBusinesses();
});
 

Комментарии:

1. Спасибо, @Тим ! Я попробовал это, но, к сожалению, никаких кубиков. Как вы думаете, возможно ли, что я не мог быть подключен к своему магазину Firestore? Все, что я видел, указывает на то, что это так, но я думаю, что не могу полностью исключить это как проблему..

2. Вы работаете с эмулятором? Если да, то, может быть, вы случайно подключены к производственным ресурсам? Я протестировал этот код в эмуляторе. Кроме того, вы на 100% уверены, что на этом пути есть данные? Нет опечатки? db.коллекция(«предприятия»)

3. Я абсолютно уверен, что путь правильный. Я использую эмулятор, хотя и не знаю, как проверить, подключен ли я к производственным ресурсам. Есть какие-нибудь советы? Спасибо!

4. Я знаю, что при вызове функции появляется предупреждающее сообщение о том, что это производственный ресурс.

Ответ №2:

Ваша getBusinesses функция такова async : затем вам нужно вызвать ее с await помощью . Затем, поскольку вы используете await функцию в облаке, вам нужно объявить ее async .

Следующее должно сработать (непроверено):

 exports.updateBusinessData = functions.https.onRequest(async (request, response) => {

    try {
        const db = admin.firestore()

        const businessesReference = db.collection('businesses')
        var businesses = []

        const getBusinesses = async () => {
            const businessData = await businessesReference.get()

            businesses = businessData.docs.map(doc => doc.data());

            for (let business in businesses) {
                console.log(business)
            }
        }

        await getBusinesses();
        // Send back the response only when all the asynchronous
        // work is done => This is why we use await above
        response.send("Businesses Updated")
        
    } catch (error) {
        response.status(500).send(error);
    }

});
 

Вероятно, вы собираетесь обновлять документы в for (let business in businesses) цикле для использования await . Вместо этого измените его на for … of цикл следующим образом:

 for (const business of businesses) {
    await db.collection('businesses').doc(...business...).update(...);
} 
 

Обновите после комментариев

Можете ли вы попробовать с этим и поделиться тем, что вы получаете из console.logs?

 exports.updateBusinessData = functions.https.onRequest(async (request, response) => {

    try {

        console.log("Function started");
        const db = admin.firestore()

        const businessesReference = db.collection('businesses');
        const businessData = await businessesReference.get();
        console.log("Snapshot size = "   businessData.size);
        const businesses = businessData.docs.map(doc => doc.data());
        for (const business of businesses) {
            console.log(business);
        }
        response.send("Businesses Updated")

    } catch (error) {
        console.log(error);
        response.status(500).send(error);
    }

});
 

Комментарии:

1. Спасибо @Renaud Tarnec ! Я тоже пытался это сделать, но это тоже не сработало. Тот же вопрос, который я задал Тиму выше — как вы думаете, возможно ли, что я не смог подключиться к своему Firestore? Все, что я видел, указывает на то, что это так, но я думаю, что не могу полностью исключить это как проблему.. Как я уже сказал в вопросе, я вошел в свою базу данных, и она печатает данные о моем проекте, как я и ожидал. Большое спасибо!

2. Можете ли вы добавить a console.log() в верхней части своей облачной функции? Просто чтобы убедиться, что вы называете это правильно. У самой облачной функции не должно возникнуть никаких проблем с вызовом Firestore. Я обновлю ответ более простым кодом (без getBusinesses функции): можете ли вы попробовать?

3. Я попробовал это, и у меня был правильный вывод. Я просматриваю все это в наборе эмуляторов Firebase, но я получаю ведение журнала, как и ожидалось. Спасибо!

4. Что произойдет, если вы развернете эту функцию? Просто чтобы проверить, не является ли это побочным эффектом эмулятора.

5. Это мой результат. Beginning execution of "_myregion_-updateBusinessData" Function started Snapshot size = 0 Finished "_myregion_-updateBusinessData" in ~1s