Загрузка файлов с файловыми потоками и облачными функциями Firebase + облачное хранилище
Я написал следующий код для загрузки своего QR-файла с использованием облачных функций Firebase
const functions = require('firebase-functions');
const qrcode = require('qrcode')
const admin = require('firebase-admin');
const spawn = require('child-process-promise').spawn;
const serviceAccount = require("./secret.json");
const gcs = require('@google-cloud/storage')();
admin.initializeApp(functions.config({
credential: admin.credential.cert(serviceAccount),
storageBucket: "https://SECRET.firebaseio.com"
}));
exports.qrcode = functions.https.onRequest((req, res) => {
const storage = admin.storage().bucket();
const dummyFile = storage.file('dummy.png')
new Promise ((resolve, reject) => qrcode.toFileStream(
dummyFile.createWriteStream()
.on('finish', resolve)
.on('error', reject),
'DummyQR'))
.then(console.log("success")) //Doing stuff here later
.catch(console.log)
res.send("<script>window.close();</script>")
});
В соответствии с документами, я должен иметь возможность подключиться к ведру, просто позвонив admin.storage().bucket();
( https://firebase.google.com/docs/storage/admin/start), однако я получаю следующую ошибку:
Error: Error occurred while parsing your function triggers.
Error: Bucket name not specified or invalid. Specify a valid bucket name via the storageBucket option when initializing the app, or specify the bucket name explicitly when calling the getBucket() method.
и поэтому я застрял и не знаю, как поступить. Если я попытаюсь вручную ввести ведро admin.storage().bucket("https://SECRET.firebaseio.com");
Я получаю ошибку
{ ApiError: Not Found
at Object.parseHttpRespBody (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:193:30)
at Object.handleResp (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:131:18)
at /user_code/node_modules/firebase-admin/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:496:12
at Request.onResponse [as _callback] (/user_code/node_modules/firebase-admin/node_modules/retry-request/index.js:195:7)
at Request.self.callback (/user_code/node_modules/firebase-admin/node_modules/request/request.js:185:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/user_code/node_modules/firebase-admin/node_modules/request/request.js:1157:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
code: 404,
errors: [ { domain: 'global', reason: 'notFound', message: 'Not Found' } ],
response: undefined,
message: 'Not Found' }
1 ответ
Похоже, вы неправильно инициализируете административный SDK. Просто вызовите initializeApp без параметров, чтобы получить все правильные значения по умолчанию:
admin.initializeApp();
Не похоже, что вам нужно инициализировать с помощью учетной записи службы с вашим кодом, так что не беспокойтесь об этом.
У меня была такая же проблема. Я просто добавил имя storageBucket при инициализации приложения, и если вы используете метод getSignedUrl, вам необходимо включить учетную запись службы, иначе срок действия этого URL-адреса истечет через неделю (как это было в моем случае).
const serviceAccount = require('/your/service/account/key/path');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: "your-storage-bucket-name.appspot.com",
});
не забудьте обновить свои функции firebase с помощью
firebase deploy --only functions
в командной строке
ОБНОВЛЕНИЕ 6 АПРЕЛЯ 2020
Срок действия подписанных URL-адресов истекает через 7 дней. Если вам нужны URL-адреса на большее время, вы должны прочитать этот ответ и эту ветку
В моем случае это была проблема, аналогичная этой (невозможно использовать облачное хранилище без указания storageBucket при инициализации приложения с помощью firebase-admin).
У меня была следующая настройка:
const admin = require("firebase-admin")
admin.initializeApp()
export * from "./api/api"
export * from "./cron/cronJobs"
export * from "./posts/postsCloudFunctions"
Изменил на:
const admin = require("firebase-admin")
export * from "./api/api"
export * from "./cron/cronJobs"
export * from "./posts/postsCloudFunctions"
admin.initializeApp()
И похоже, проблема в том, что initializeApp() не вызывался до доступа к ведру хранилища.
Вы должны изменить
storageBucket: "имя-хранилища-ведра, заданное в хранилище firebase"
к
storageBucket: "
Вы можете найти BUCKET_NAME, как показано на рисунке ниже:
У меня такая же проблема при загрузке изображения в хранилище firebase:
Ошибка: имя сегмента не указано или недействительно. Укажите допустимое имя сегмента с помощью параметра storageBucket при инициализации приложения или укажите имя сегмента явно при вызове метода getBucket(). ndlers\users.js:130:8) в Busboy.emit (events.js:189:13) в Busboy.emit (E:\react-project\socialape-functions\functions\node_modules\busboy\lib\main.js:37:33) в E:\react-project\socialape-functions\functions\node_modules\busboy\lib\types\multipart.js:52:13 в process._tickCallback (internal/process/next_tick.js:61:11)
Затем я добавляю storageBucket в функцию администратора
var admin = require("firebase-admin");
var serviceAccount = require("your service account key file path);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://your-app-1234.firebaseio.com",
storageBucket: "your-storage-bucket-name given in firebase storage"
});
const db = admin.firestore();
module.exports = { admin, db };
После добавления ведра в функции администратора он работает.