В этом ответе будут обобщены варианты получения URL-адреса загрузки при загрузке файла в Google / Firebase Cloud Storage. Существует три типа URL-адресов для загрузки:
- подписанные URL-адреса загрузки, которые являются временными и имеют функции безопасности
- URL-адреса загрузки токенов, которые являются постоянными и имеют функции безопасности
- общедоступные URL-адреса загрузки, которые являются постоянными и не защищенными
Есть три способа получить URL для загрузки токена. Два других URL-адреса загрузки имеют только один способ получить их.
Из консоли Firebase Storage
Вы можете получить 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 строк кода для относительно простой структуры базы данных. Если ваша база данных сложна, это будет кошмар. И вы можете загружать файлы из внешнего интерфейса, но это сделает ваши учетные данные доступными для всех, кто скачивает ваше приложение. Таким образом, для большинства проектов вы захотите загрузить файлы из серверной части Node или из облачных функций 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-адреса загрузки истек. Я внес различные изменения в свой код, и все работало ... пока через неделю все не рухнуло. Это продолжалось более месяца разочарования.
Сделайте свой файл общедоступным
Вы можете установить разрешения для публичного чтения вашего файла, как описано в документации . Это можно сделать из браузера облачного хранилища или с вашего сервера Node. Вы можете сделать один файл общедоступным, каталог или всю базу данных Storage. Вот код узла:
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
модуля Node. Четыре строки кода, и вы можете создать свой собственный 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
(то есть в вашем сервере Node). Я хочу загрузить файл из Google Cloud Functions и получить URL для загрузки токена.