Получить URL-адрес загрузки из файла, загруженного с помощью облачных функций для Firebase
После загрузки файла в Firebase Storage с функциями для Firebase я хотел бы получить URL-адрес загрузки файла.
У меня есть это:
...
return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {
// Get the download url of file
});
Объектный файл имеет много параметров. Даже один по имени mediaLink
, Однако, если я пытаюсь получить доступ к этой ссылке, я получаю эту ошибку:
Анонимные пользователи не имеют доступа к объекту storage.objects.get...
Может кто-нибудь сказать мне, как получить общедоступный URL-адрес загрузки?
Спасибо
27 ответов
Вам нужно сгенерировать подписанный URL-адрес с помощью getSignedURL через модуль NPM @ google-cloud / storage.
Пример:
const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'});
// ...
const bucket = gcs.bucket(bucket);
const file = bucket.file(fileName);
return file.getSignedUrl({
action: 'read',
expires: '03-09-2491'
}).then(signedUrls => {
// signedUrls[0] contains the file's public URL
});
Вам нужно будет инициализировать @google-cloud/storage
с учетными данными вашей учетной записи службы в качестве учетных данных приложения по умолчанию будет недостаточно.
ОБНОВЛЕНИЕ: Доступ к Cloud Storage SDK теперь можно получить через Firebase Admin SDK, который действует как обертка вокруг @google-cloud/storage. Единственный способ это сделать, если вы либо:
- Инициируйте SDK со специальной учетной записью службы, обычно через второй экземпляр, отличный от используемого по умолчанию.
- Или без учетной записи службы, предоставив учетной записи службы App Engine по умолчанию разрешение "signBlob".
В этом ответе будут представлены варианты получения URL-адреса для загрузки при загрузке файла в Google/Firebase Cloud Storage. Существует три типа URL для загрузки:
- подписанные URL для загрузки, которые являются временными и имеют функции безопасности
- URL загрузки токенов, которые являются постоянными и имеют функции безопасности
- общедоступные URL-адреса для загрузки, которые являются постоянными и не имеют безопасности
Есть три способа получить URL для загрузки токена. У двух других URL-адресов для загрузки есть только один способ получить их.
Из консоли хранилища Firebase
Вы можете получить URL для загрузки из консоли Firebase Storage:
URL загрузки выглядит следующим образом:
https://firebasestorage.googleapis.com/v0/b/languagetwo-cd94d.appspot.com/o/Audio%2FEnglish%2FUnited_States-OED-0%2Fabout.mp3?alt=media&token=489c48b3-23fb-4270-bd85-0a328d2808e5
Первая часть - это стандартный путь к вашему файлу. В конце есть жетон. Этот URL-адрес загрузки является постоянным, то есть срок его действия не истекает, хотя вы можете отозвать его.
getDownloadURL() из внешнего интерфейса
Документация говорит нам использовать getDownloadURL()
:
let url = await firebase.storage().ref('Audio/English/United_States-OED-' + i +'/' + $scope.word.word + ".mp3").getDownloadURL();
Он получает тот же URL-адрес для загрузки, который вы можете получить из консоли Firebase Storage. Этот метод прост, но требует, чтобы вы знали путь к вашему файлу, который в моем приложении составляет около 300 строк кода, для относительно простой структуры базы данных. Если ваша база данных сложна, это будет кошмар. И вы можете загружать файлы из внешнего интерфейса, но это предоставит ваши учетные данные любому, кто загружает ваше приложение. Таким образом, для большинства проектов вы захотите загрузить свои файлы с вашего внутреннего узла или облачных функций Google, затем получите URL-адрес для загрузки и сохраните его в своей базе данных вместе с другими данными о вашем файле.
getSignedUrl() для временных URL загрузки
getSignedUrl() легко использовать из серверной части Node или из облачных функций Google:
function oedPromise() {
return new Promise(function(resolve, reject) {
http.get(oedAudioURL, function(response) {
response.pipe(file.createWriteStream(options))
.on('error', function(error) {
console.error(error);
reject(error);
})
.on('finish', function() {
file.getSignedUrl(config, function(err, url) {
if (err) {
console.error(err);
return;
} else {
resolve(url);
}
});
});
});
});
}
Подписанный URL для загрузки выглядит следующим образом:
https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio%2FSpanish%2FLatin_America-Sofia-Female-IBM%2Faqu%C3%AD.mp3?GoogleAccessId=languagetwo-cd94d%40appspot.gserviceaccount.com&Expires=4711305600&Signature=WUmABCZIlUp6eg7dKaBFycuO%2Baz5vOGTl29Je%2BNpselq8JSl7%2BIGG1LnCl0AlrHpxVZLxhk0iiqIejj4Qa6pSMx%2FhuBfZLT2Z%2FQhIzEAoyiZFn8xy%2FrhtymjDcpbDKGZYjmWNONFezMgYekNYHi05EPMoHtiUDsP47xHm3XwW9BcbuW6DaWh2UKrCxERy6cJTJ01H9NK1wCUZSMT0%2BUeNpwTvbRwc4aIqSD3UbXSMQlFMxxWbPvf%2B8Q0nEcaAB1qMKwNhw1ofAxSSaJvUdXeLFNVxsjm2V9HX4Y7OIuWwAxtGedLhgSleOP4ErByvGQCZsoO4nljjF97veil62ilaQ%3D%3D
Подписанный URL имеет срок действия и длинную подпись. В документации для командной строки gsutil signurl -d говорится, что подписанные URL-адреса являются временными: срок действия по умолчанию составляет один час, а максимальный срок действия - семь дней.
Я собираюсь разглагольствовать здесь, что getSignedUrl никогда не говорит, что ваш подписанный URL истекает через неделю. Код документации имеет 3-17-2025
в качестве даты истечения срока действия, предполагая, что вы можете установить срок годности в будущем. Мое приложение работало отлично, а через неделю рухнуло. В сообщении об ошибке говорится, что подписи не совпадают, а URL-адрес загрузки истек. Я сделал различные изменения в своем коде, и все работало... пока все не рухнуло неделю спустя. Это продолжалось более месяца разочарования.
Сделайте ваш файл общедоступным
Вы можете установить права доступа к вашему файлу для публичного чтения, как описано в документации. Это можно сделать из браузера Cloud Storage или с вашего Node-сервера. Вы можете сделать один файл общедоступным, каталог или всю вашу базу данных хранилища. Вот код узла:
var webmPromise = new Promise(function(resolve, reject) {
var options = {
destination: ('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3'),
predefinedAcl: 'publicRead',
contentType: 'audio/' + audioType,
};
synthesizeParams.accept = 'audio/webm';
var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm');
textToSpeech.synthesize(synthesizeParams)
.then(function(audio) {
audio.pipe(file.createWriteStream(options));
})
.then(function() {
console.log("webm audio file written.");
resolve();
})
.catch(error => console.error(error));
});
Результат будет выглядеть так в вашем облачном хранилище:
Любой может затем использовать стандартный путь для загрузки вашего файла:
https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/English/United_States-OED-0/system.mp3
Другой способ сделать файл общедоступным - использовать метод makePublic (). Я не смог заставить это работать, сложно сделать правильный путь и путь к файлу.
Интересной альтернативой является использование списков контроля доступа. Вы можете сделать файл доступным только пользователям, которых вы включили в список, или использовать authenticatedRead
сделать файл доступным для всех, кто вошел в систему из учетной записи Google. Если бы была опция "любой, кто вошел в мое приложение с помощью Firebase Auth", я бы использовал это, так как это ограничило бы доступ только для моих пользователей.
Создайте свой собственный URL для загрузки с помощью firebaseStorageDownloadTokens
Несколько ответов описывают недокументированное свойство объекта Google Storage firebaseStorageDownloadTokens
, При этом вы можете указать Storage токен, который хотите использовать. Вы можете сгенерировать токен с помощью uuid
Узловой модуль. Четыре строки кода, и вы можете создать свой собственный URL-адрес для загрузки, тот же URL-адрес для загрузки, который вы получаете с консоли или getDownloadURL()
, Четыре строки кода:
const uuidv4 = require('uuid/v4');
const uuid = uuidv4();
metadata: { firebaseStorageDownloadTokens: uuid }
https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm') + "?alt=media&token=" + uuid);
Вот код в контексте:
var webmPromise = new Promise(function(resolve, reject) {
var options = {
destination: ('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3'),
contentType: 'audio/' + audioType,
metadata: {
metadata: {
firebaseStorageDownloadTokens: uuid,
}
}
};
synthesizeParams.accept = 'audio/webm';
var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm');
textToSpeech.synthesize(synthesizeParams)
.then(function(audio) {
audio.pipe(file.createWriteStream(options));
})
.then(function() {
resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm') + "?alt=media&token=" + uuid);
})
.catch(error => console.error(error));
});
Это не опечатка - вы должны вложить firebaseStorageDownloadTokens
в двойных слоях metadata:
!
Дуг Стивенсон отметил, что firebaseStorageDownloadTokens
не является официальной функцией Google Cloud Storage. Вы не найдете его ни в одной документации Google, и нет никаких обещаний, что это будет в будущей версии @google-cloud
, мне нравится firebaseStorageDownloadTokens
потому что это единственный способ получить то, что я хочу, но у него есть "запах", который небезопасно использовать.
Почему нет getDownloadURL() от узла?
Как писал @Clinton, Google должен сделать file.getDownloadURL()
метод в @google-cloud/storage
(т. е. ваш конец узла). Я хочу загрузить файл из Google Cloud Functions и получить URL-адрес для загрузки токена.
Вот пример того, как указать токен загрузки при загрузке:
const UUID = require("uuid-v4");
const fbId = "<YOUR APP ID>";
const fbKeyFile = "./YOUR_AUTH_FIlE.json";
const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile});
const bucket = gcs.bucket(`${fbId}.appspot.com`);
var upload = (localFile, remoteFile) => {
let uuid = UUID();
return bucket.upload(localFile, {
destination: remoteFile,
uploadType: "media",
metadata: {
contentType: 'image/png',
metadata: {
firebaseStorageDownloadTokens: uuid
}
}
})
.then((data) => {
let file = data[0];
return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
});
}
затем позвоните с
upload(localPath, remotePath).then( downloadURL => {
console.log(downloadURL);
});
Ключевым моментом здесь является то, что есть metadata
объект, вложенный в metadata
Опция собственности. настройка firebaseStorageDownloadTokens
значение uuid-v4 скажет Cloud Storage использовать его в качестве своего открытого токена авторизации.
Большое спасибо @martemorfosis
Если вы работаете над проектом Firebase, вы можете создавать подписанные URL-адреса в облачной функции, не включая другие библиотеки и не загружая файл учетных данных. Вам просто нужно включить IAM API и добавить роль в существующую учетную запись службы (см. Ниже).
Инициализируйте библиотеку администратора и получите ссылку на файл, как обычно:
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
admin.initializeApp(functions.config().firebase)
const myFile = admin.storage().bucket().file('path/to/my/file')
Затем вы создаете подписанный URL с
myFile.getSignedUrl({action: 'read', expires: someDateObj}).then(urls => {
const signedUrl = urls[0]
})
Убедитесь, что ваша учетная запись службы Firebase имеет достаточные разрешения для запуска этого
- Перейдите в консоль API Google и включите API IAM ( https://console.developers.google.com/apis/api/iam.googleapis.com/overview).
- В консоли API перейдите в главное меню "IAM & admin" -> "IAM".
- Нажмите "Изменить" для роли "Учетная запись службы App Engine по умолчанию".
- Нажмите "Добавить другую роль" и добавьте роль "Создатель токена учетной записи службы".
- Сохраните и подождите минуту, чтобы изменения распространялись
С ванильной конфигурацией Firebase при первом запуске приведенного выше кода вы получите сообщение об ошибке API Identity and Access Management (IAM) ранее не использовалось в проекте XXXXXX или было отключено., Если вы перейдете по ссылке в сообщении об ошибке и включите IAM API, вы получите еще одну ошибку: для выполнения этой операции на служебной учетной записи my-service-account требуется разрешение iam.serviceAccounts.signBlob. Добавление роли Token Creator устраняет эту вторую проблему с разрешениями.
Я предлагаю использовать опцию predefinedAcl: 'publicRead'
при загрузке файла с помощью Cloud Storage NodeJS 1.6.x или +:
const options = {
destination: yourFileDestination,
predefinedAcl: 'publicRead'
};
bucket.upload(attachment, options);
Затем получить общедоступный URL-адрес так же просто, как:
bucket.upload(attachment, options).then(result => {
const file = result[0];
return file.getMetadata();
}).then(results => {
const metadata = results[0];
console.log('metadata=', metadata.mediaLink);
}).catch(error => {
console.error(error);
});
Это то, что я сейчас использую, это просто и работает без нареканий.
Вам не нужно ничего делать с Google Cloud. Это работает из коробки с Firebase..
// Save the base64 to storage.
const file = admin.storage().bucket('url found on the storage part of firebase').file(`profile_photos/${uid}`);
await file.save(base64Image, {
metadata: {
contentType: 'image/jpeg',
},
predefinedAcl: 'publicRead'
});
const metaData = await file.getMetadata()
const url = metaData[0].mediaLinkenter
Благодаря последним изменениям в ответе объекта функций вы можете получить все, что вам нужно, чтобы "сшить" вместе URL-адрес загрузки следующим образом:
const img_url = 'https://firebasestorage.googleapis.com/v0/b/[YOUR BUCKET]/o/'
+ encodeURIComponent(object.name)
+ '?alt=media&token='
+ object.metadata.firebaseStorageDownloadTokens;
console.log('URL',img_url);
Для тех, кто интересуется, куда должен идти файл serviceAccountKey.json Firebase Admin SDK. Просто поместите его в папку функций и разверните как обычно.
Это все еще сбивает меня с толку, почему мы не можем просто получить URL-адрес загрузки из метаданных, как мы делаем в Javascript SDK. Создание URL, срок действия которого истекает, и сохранение его в базе данных нежелательно.
Один метод, который я использую с успехом, состоит в том, чтобы установить значение UUID v4 для ключа с именем firebaseStorageDownloadTokens
в метаданных файла после того, как он завершит загрузку и затем сам соберет URL загрузки, следуя структуре, используемой Firebase для генерации этих URL, например:
https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]
Я не знаю, насколько "безопасно" использовать этот метод (учитывая, что Firebase может изменить способ генерации URL-адресов для загрузки в будущем), но его легко реализовать.
Извините, но я не могу оставить комментарий к вашему вопросу выше из-за отсутствия репутации, поэтому я включу его в этот ответ.
Сделайте, как указано выше, сгенерировав подписанный URL-адрес, но вместо использования service-account.json я думаю, что вы должны использовать serviceAccountKey.json, который вы можете сгенерировать в (замените YOURPROJECTID соответствующим образом)
https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk
Пример:
const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'});
// ...
const bucket = gcs.bucket(bucket);
// ...
return bucket.upload(tempLocalFile, {
destination: filePath,
metadata: {
contentType: 'image/jpeg'
}
})
.then((data) => {
let file = data[0]
file.getSignedUrl({
action: 'read',
expires: '03-17-2025'
}, function(err, url) {
if (err) {
console.error(err);
return;
}
// handle url
})
Я не могу комментировать ответ, который дал Джеймс Дэниелс, но я думаю, что это очень важно прочитать.
Выдача подписанного URL-адреса Как он это сделал, во многих случаях кажется довольно плохим и, возможно, опасным. Согласно документации Firebase, срок действия подписанного URL истекает через некоторое время, поэтому добавление его в базу данных приведет к появлению пустого URL через определенный промежуток времени.
Возможно, что там неправильно истолкована документация, а срок действия подписанного URL не истекает, что может привести к проблемам с безопасностью. Ключ кажется одинаковым для каждого загруженного файла. Это означает, что, получив URL-адрес одного файла, кто-то может легко получить доступ к файлам, к которым он не имеет доступа, просто зная их имена.
Если бы я не понял этого, я бы хотел исправить. В противном случае кто-то должен, вероятно, обновить вышеуказанное решение. Если я могу ошибаться там
FireBaser здесь
В версию 11.10 Admin SDK для Node.js добавленgetDownloadURL()
метод. Пример его использования можно найти в документации по получению общего URL-адреса :
const { getStorage, getDownloadURL } = require('firebase-admin/storage');
const fileRef = getStorage().bucket("my-bucket").file("my-file");
const downloadURL= await getDownloadURL(fileRef);
Использовать
file.publicUrl()
Асинхронный/ожидание
const bucket = storage.bucket('bucket-name');
const uploadResponse = await bucket.upload('image-name.jpg');
const downloadUrl = uploadResponse[0].publicUrl();
Перезвонить
const bucket = storage.bucket('bucket-name');
bucket.upload('image-name.jpg', (err, file) => {
if(!file) {
throw err;
}
const downloadUrl = file.publicUrl();
})
The
downloadUrl
будет
"https://storage.googleapis.com/bucket-name/image-name.jpg"
.
Обратите внимание, что для того, чтобы приведенный выше код работал, вы должны сделать корзину или файл общедоступными. Для этого следуйте инструкциям здесь https://cloud.google.com/storage/docs/access-control/making-data-public . Кроме того, я импортировал
@google-cloud/storage
package напрямую, а не через Firebase SDK.
Если вы используете предопределенное значение списков управления доступом publicRead, вы можете загрузить файл и получить к нему доступ с очень простой структурой URL:
// Upload to GCS
const opts: UploadOptions = {
gzip: true,
destination: dest, // 'someFolder/image.jpg'
predefinedAcl: 'publicRead',
public: true
};
return bucket.upload(imagePath, opts);
Затем вы можете построить URL так:
const storageRoot = 'https://storage.googleapis.com/';
const bucketName = 'myapp.appspot.com/'; // CHANGE TO YOUR BUCKET NAME
const downloadUrl = storageRoot + bucketName + encodeURIComponent(dest);
Ответ Laurent работает лучше всего
const uploadOptions: UploadOptions = {
public: true
};
const bucket = admin.storage().bucket();
[ffile] = await bucket.upload(oPath, uploadOptions);
ffile.metadata.mediaLink // this is what you need
У меня была та же проблема, однако я смотрел на код примера функции firebase вместо README. И ответы в этой теме тоже не помогли...
Вы можете избежать передачи файла конфигурации, выполнив следующие действия:
Перейдите в Cloud Console вашего проекта > IAM & admin> IAM, найдите учетную запись службы App Engine по умолчанию и добавьте роль создателя токена учетной записи службы к этому участнику. Это позволит вашему приложению создавать подписанные общедоступные URL-адреса для изображений.
источник: функция автоматического создания миниатюр README
Ваша роль для движка приложения должна выглядеть следующим образом:
Я видел это в документации по хранилищу администратора
const options = {
version: 'v4',
action: 'read',
expires: Date.now() + 15 * 60 * 1000, // 15 minutes
};
// Get a v4 signed URL for reading the file
const [url] = await storage
.bucket(bucketName)
.file(filename)
.getSignedUrl(options);
console.log('Generated GET signed URL:');
console.log(url);
console.log('You can use this URL with any user agent, for example:');
console.log(`curl '${url}'`);
Это работает, если вам просто нужен публичный файл с простым URL. Обратите внимание, что это может отменить ваши правила хранения Firebase.
bucket.upload(file, function(err, file) {
if (!err) {
//Make the file public
file.acl.add({
entity: 'allUsers',
role: gcs.acl.READER_ROLE
}, function(err, aclObject) {
if (!err) {
var URL = "https://storage.googleapis.com/[your bucket name]/" + file.id;
console.log(URL);
} else {
console.log("Failed to set permissions: " + err);
}
});
} else {
console.log("Upload failed: " + err);
}
});
Без signedURL()
с помощью makePublic()
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp()
var bucket = admin.storage().bucket();
// --- [Above] for admin related operations, [Below] for making a public url from a GCS uploaded object
const { Storage } = require('@google-cloud/storage');
const storage = new Storage();
exports.testDlUrl = functions.storage.object().onFinalize(async (objMetadata) => {
console.log('bucket, file', objMetadata.bucket + ' ' + objMetadata.name.split('/').pop()); // assuming file is in folder
return storage.bucket(objMetadata.bucket).file(objMetadata.name).makePublic().then(function (data) {
return admin.firestore().collection('publicUrl').doc().set({ publicUrl: 'https://storage.googleapis.com/' + objMetadata.bucket + '/' + objMetadata.name }).then(writeResult => {
return console.log('publicUrl', writeResult);
});
});
});
Для тех, кто использует Firebase SDK иadmin.initializeApp
:
1 - Сгенерируйте закрытый ключ и поместите в папку /functions.
2 - Настройте ваш код следующим образом:
const serviceAccount = require('../../serviceAccountKey.json');
try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}
Try/catch заключается в том, что я использую index.js, который импортирует другие файлы и создает одну функцию для каждого файла. Если вы используете один файл index.js со всеми функциями, вы должны admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));
,
Это лучшее, что я придумал. Это избыточно, но единственное разумное решение, которое сработало для меня.
await bucket.upload(localFilePath, {destination: uploadPath, public: true});
const f = await bucket.file(uploadPath)
const meta = await f.getMetadata()
console.log(meta[0].mediaLink)
Начиная с Firebase 6.0.0 я мог получить доступ к хранилищу напрямую с помощью администратора:
const bucket = admin.storage().bucket();
Поэтому мне не нужно было добавлять служебную учетную запись. Затем установка UUID, как указано выше, сработала для получения URL-адреса firebase.
тлдр; Загрузка большого двоичного объекта и получение URL-адреса изображения:
const file = storage.bucket().file(`images/${imageName}.jpeg`)
await file.save(image)
const imgUrl = file.metadata.mediaLink
Для тех, кто пытается использовать параметр токена для совместного использования файла и хотел бы использовать команду gsutil, вот как я это сделал:
Сначала вам нужно пройти аутентификацию, запустив:
gcloud auth
Затем запустите:
gsutil setmeta -h "x-goog-meta-firebaseStorageDownloadTokens:$FILE_TOKEN"
gs://$FIREBASE_REPO/$FILE_NAME
Затем вы можете скачать файл по следующей ссылке:
https://firebasestorage.googleapis.com/v0/b/$FIREBASE_REPO/o/$FILE_NAME?alt=media&token=$FILE_TOKEN
Из Admin SDK вы не можете получить токен загрузки, сгенерированный Firebase для загруженного файла, но вы можете установить этот токен при загрузке, добавив его в метаданные.
Для тех, кто работает над Python SDK. Вот как это сделать:
from firebase_admin import storage
from uuid import uuid4
bucket = storage.bucket()
blob = bucket.blob(path_to_file)
token = str(uuid4()) # Random ID
blob.metadata = {
"firebaseStorageDownloadTokens": token
}
blob.upload_from_file(file)
Теперь вы загрузили файл и получили токен URL. Теперь вы можете сохранить токен (или даже полный URL-адрес загрузки) в свою базу данных (например, Firestore) и отправить его клиенту при запросе файла, а затем заставить клиента самостоятельно получить файл.
Полный URL загрузки выглядит следующим образом:
https://firebasestorage.googleapis.com/v0/b/{bucket_name}/o/{file_name}?alt=media&token={token}
Я уже публикую свой ответ... в URL-адресе ниже, где вы можете получить полный код с решением
const uuidv4 = require('uuid/v4');
const uuid = uuidv4();
const os = require('os')
const path = require('path')
const cors = require('cors')({ origin: true })
const Busboy = require('busboy')
const fs = require('fs')
var admin = require("firebase-admin");
var serviceAccount = {
"type": "service_account",
"project_id": "xxxxxx",
"private_key_id": "xxxxxx",
"private_key": "-----BEGIN PRIVATE KEY-----\jr5x+4AvctKLonBafg\nElTg3Cj7pAEbUfIO9I44zZ8=\n-----END PRIVATE KEY-----\n",
"client_email": "xxxx@xxxx.iam.gserviceaccount.com",
"client_id": "xxxxxxxx",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-5rmdm%40xxxxx.iam.gserviceaccount.com"
}
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: "xxxxx-xxxx" // use your storage bucket name
});
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/uploadFile', (req, response) => {
response.set('Access-Control-Allow-Origin', '*');
const busboy = new Busboy({ headers: req.headers })
let uploadData = null
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
const filepath = path.join(os.tmpdir(), filename)
uploadData = { file: filepath, type: mimetype }
console.log("-------------->>",filepath)
file.pipe(fs.createWriteStream(filepath))
})
busboy.on('finish', () => {
const bucket = admin.storage().bucket();
bucket.upload(uploadData.file, {
uploadType: 'media',
metadata: {
metadata: { firebaseStorageDownloadTokens: uuid,
contentType: uploadData.type,
},
},
})
.catch(err => {
res.status(500).json({
error: err,
})
})
})
busboy.end(req.rawBody)
});
exports.widgets = functions.https.onRequest(app);
Если вы получаете сообщение об ошибке:
Google Cloud Functions: require (â € ¦) не является функцией
попробуй это:
const {Storage} = require('@google-cloud/storage');
const storage = new Storage({keyFilename: 'service-account-key.json'});
const bucket = storage.bucket(object.bucket);
const file = bucket.file(filePath);
.....