Облачные функции, триггер Firestore, рекурсивное удаление не работает

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

Вопрос:

В настоящее время я пытаюсь удалить все вложенные данные hirachy, когда некоторые документы удаляются с помощью триггера Firestore

а мой код и код ошибки приведены ниже

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

admin.initializeApp({   
}
);


exports.firestore_delete_trigger_test = functions.firestore
  .document('collection1/{docs1}/collection2/{docs2}')
  .onDelete(async (change: any, context: any) => {     
    
    const path = change.path;

    await firebase_tools.firestore
      .delete(path, {
        project: process.env.GCLOUD_PROJECT,
        recursive: true,
        yes: true,
        token: functions.config().fb.token
      });

    return {
      path: path
    };

  });
 

и код ошибки приведен ниже

 FirebaseError: Must specify a path.
    at Object.reject (/workspace/node_modules/firebase-tools/lib/utils.js:122:27) 
 

почему он показывает код ошибки? Я не хочу «вызываемых функций» из-за безопасности

Ответ №1:

Никогда не используйте any при написании машинописного текста, так как вы, по сути, «выключаете» машинопись и теряете ценную информацию о типе, например, о том, почему ваш код не работает.

Если вы используете следующие строки, тип change (который должен быть snapshot ) и context автоматически устанавливается как QueryDocumentSnapshot и EventContext соответственно, как определено onDelete методом.

 exports.firestore_delete_trigger_test = functions.firestore
  .document('collection1/{docs1}/collection2/{docs2}')
  .onDelete(async (snapshot, context) => {

  });
 

Примечание: A QueryDocumentSnapshot похож на обычный DocumentSnapshot , но он гарантированно существует ( snap.exists всегда возвращается true и snap.data() никогда не вернется undefined ).

Теперь , когда тип восстановлен snapshot , вы увидите, что не можете прочитать свойство, вызванное path из него, поскольку оно не задано. В вашем текущем коде path будет просто установлено значение undefined , что приведет к ошибке , в которой говорится, что вам нужно указать путь.

 const path = snapshot.path; // ✖ Property 'path' does not exist on type 'QueryDocumentSnapshot'. ts(2339)
 

Это потому path , что является свойством DocumentReference . Чтобы получить базовый снимок DocumentReference , вы получаете доступ к его ref свойству.

 const path = snapshot.ref.path; // ✔
 

Затем в узле 10 Облачные функции список доступных переменных среды был изменен и process.env.GCLOUD_PROJECT удален. Чтобы получить текущий идентификатор проекта, вы можете использовать либо

 const PROJECT_ID = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
 

или

 const defaultApp = admin.intializeApp();

const PROJECT_ID = defaultApp.options.projectId;
 

Это затем делает ваш (модернизированный) код:

 import * as admin from 'firebase-admin';
import * as firebase_tools from 'firebase-tools';
import * as functions from 'firebase-functions';

const PROJECT_ID = JSON.parse(process.env.FIREBASE_CONFIG).projectId;

admin.initializeApp(); // config is automatically filled if left empty
                       // although it isn't needed here

export const firestore_delete_trigger_test = functions.firestore
  .document('collection1/{docs1}/collection2/{docs2}')
  .onDelete(async (snapshot, context) => {     
    const path = snapshot.ref.path;

    await firebase_tools.firestore
      .delete(path, {
        project: PROJECT_ID,
        recursive: true,
        yes: true,
        token: functions.config().fb.token
      });

    return {
      path: path
    };
  });
 

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

1. вау.. такой впечатляющий ответ, спасибо, я попробую это. и как вы обычно получаете эту информацию??

2. первоначальная проблема решена, и возникла новая ошибка. Вы знаете, почему это происходит? Ошибка FirebaseError: Не удалось удалить документы Ошибка FirebaseError: Ошибка HTTP: 401, Неизвестная ошибка во время ожидания. <анонимный> (/рабочее пространство/node_modules/firebase-инструменты/lib/firestore/удалить.js:251:28) в listOnTimeout (внутренние/таймеры.js:554:17) в processTimers (внутренние/таймеры.js:497:7) Я попробовал это, но все еще не решил экспорт.firestore_delete_trigger_test= функции.RunWith({ Тайм-ауты: 540, память: ‘2 ГБ’ }). пожарный магазин …/

3. @rounpaleum HTTP 401 Несанкционированный предполагает, что используемый вами токен ( functions.config().fb.token ) недействителен. Обновите свою firebase-tools систему и сгенерируйте новый токен с помощью firebase login:ci .