NodeJS: сбой при удалении хранилища firebase-tools

Я пытаюсь удалить вложенную коллекцию при удалении родительского документа.

Для этого я создал следующую облачную функцию:

import { firestore, logger } from 'firebase-functions';
import { recursiveDelete } from '../utils/db';

export const deleteListItems = firestore.document('owners/{owner}/lists/{list}').onDelete(snap => {
  const collPath = snap.ref.collection('items').path;
  logger.info('Why do you hate me?');
  logger.debug({ collPath });
  return recursiveDelete(collPath);
});

---------
db.ts
---------------------------------
import * as functions from 'firebase-functions';
const firebase_tools = require('firebase-tools');

export const recursiveDelete = (path: string): Promise<any> => {
  console.debug({ project: process.env.GCLOUD_PROJECT });
  console.debug({ token: functions.config().fb.token });

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

Из моего журнала я вижу, что путь, который я пытаюсь удалить, правильный, owners/G-470728052545159171/lists/anime/items. Я также вижу, что присутствуют значения проекта и токена.

Однако я вижу следующую ошибку в журналах облачных функций:

deleteListItems 
FirebaseError: Deletion failed. Errors: Failed to fetch documents to delete >= 3 times..
   at Timeout.<anonymous> (/workspace/node_modules/firebase-tools/lib/firestore/delete.js:272:32)
   at listOnTimeout (internal/timers.js:554:17)
   at processTimers (internal/timers.js:497:7) 

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

Я попытался запустить эквивалентную команду на своей консоли:

firebase firestore:delete -r -y owners/G-470728052545159171/lists/anime/items

Это работает, как ожидалось, даже если документ списка (аниме) уже удален, поэтому я не понимаю, почему тот, что в функции, не работает.

РЕДАКТИРОВАТЬ: установите DEBUG env var.

Вывод отладки:

2:05:30.175 PM
deleteListItems
[2021-04-17T18:05:30.171Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
2:05:30.176 PM
deleteListItems
[2021-04-17T18:05:30.175Z] > authorizing via --token option
2:05:30.176 PM
deleteListItems
[2021-04-17T18:05:30.176Z] [iam] checking project watchlist-bot for permissions ["datastore.entities.delete","datastore.entities.list","firebase.projects.get"] 
2:05:30.246 PM
deleteListItems
[2021-04-17T18:05:30.244Z] > refreshing access token with scopes: ["email","https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","openid"] 
2:05:30.246 PM
deleteListItems
[2021-04-17T18:05:30.245Z] >>> HTTP REQUEST POST https://www.googleapis.com/oauth2/v3/token   
2:05:30.246 PM
deleteListItems
 <request body omitted> 
2:05:30.478 PM
deleteListItems
[2021-04-17T18:05:30.477Z] <<< HTTP RESPONSE 400 {"cache-control":"no-cache, no-store, max-age=0, must-revalidate","date":"Sat, 17 Apr 2021 18:05:30 GMT","pragma":"no-cache","expires":"Mon, 01 Jan 1990 00:00:00 GMT","content-type":"application/json; charset=utf-8","vary":"X-Origin, Referer, Origin,Accept-Encoding","server":"scaffolding on HTTPServer2","x-xss-protection":"0","x-frame-options":"SAMEORIGIN","x-content-type-options":"nosniff","alt-svc":"h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"","accept-ranges":"none","transfer-encoding":"chunked"} 
2:05:30.581 PM
deleteListItems
[2021-04-17T18:05:30.581Z] <<< HTTP RESPONSE 401 {"www-authenticate":"Bearer realm=\"https://accounts.google.com/\", error=\"invalid_token\"","vary":"X-Origin, Referer, Origin,Accept-Encoding","content-type":"application/json; charset=UTF-8","date":"Sat, 17 Apr 2021 18:05:30 GMT","server":"ESF","cache-control":"private","x-xss-protection":"0","x-frame-options":"SAMEORIGIN","x-content-type-options":"nosniff","server-timing":"gfet4t7; dur=4","alt-svc":"h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"","accept-ranges":"none","transfer-encoding":"chunked"} 
2:05:30.581 PM
deleteListItems
[2021-04-17T18:05:30.581Z] <<< HTTP RESPONSE BODY {"error":{"code":401,"message":"Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.","status":"UNAUTHENTICATED"}} 
2:05:30.583 PM
deleteListItems
[2021-04-17T18:05:30.583Z] [iam] error while checking permissions, command may fail: FirebaseError: HTTP Error: 401, Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.

Похоже, с моим токеном возникла проблема, о которой я подозревал, но не знаю почему. Я сгенерировал токен, используя firebase login:ci, как они указали. Потом выставил с помощью firebase functions:config:set fb.token=***.


comment
Непосредственно перед require('firebase-tools'); добавьте process.env.DEBUG = true. Это должно дать больше (возможно, слишком много) информации о том, что происходит. В документации указано, что для некоторых функций требуется доступ к файловой системе, но я сомневаюсь, что это так.   -  person samthecodingman    schedule 17.04.2021
comment
@samthecodingman Я включил интересные части своего отладочного вывода. Любые идеи?   -  person Ace    schedule 17.04.2021


Ответы (1)


Как видно из сообщений журнала, в вашем текущем токене, созданном login:ci, неправильно не хватает области "https://www.googleapis.com/auth/cloud-platform". Попробуйте обновить свой firebase-tools экземпляр, который вы использовали для создания токена, и попробуйте создать новый токен.

Что касается того, почему эта же ошибка не появляется в вашей локальной системе: в вашей системе firebase-tools использует ваши полные учетные данные (для развертывания кода и т. Д.), А не учетные данные с целевыми областями.

person samthecodingman    schedule 18.04.2021
comment
Это сработало, спасибо. Но мне интересно: истечет ли срок действия этого токена? - person Ace; 19.04.2021
comment
@Ace Сгенерированный токен является токеном обновления OAuth 2. Если вы не отзовете его из своей учетной записи Google (отображается как Firebase CLI) или измените пароль учетной записи, срок действия этого токена не истечет. Однако токены доступа / идентификатора, сгенерированные с его помощью, будут иметь срок действия 1 час. - person samthecodingman; 20.04.2021
comment
Понял. Спасибо. - person Ace; 21.04.2021