Ця відповідь підсумовує варіанти отримання 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 Cloud Functions, а потім отримати URL-адресу для завантаження та зберегти її у вашу базу даних разом з іншими даними про ваш файл.
getSignedUrl () для тимчасових URL-адрес завантаження
getSignedUrl () простий у використанні із заднього кінця вузла чи функцій Google Cloud:
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 ніколи не каже, що термін дії вашої підписаної дати закінчиться через тиждень. Код документації має 3-17-2025дату закінчення терміну придатності, що передбачає, що ви можете встановити роки закінчення терміну придатності в майбутньому. Мій додаток працював ідеально, а потім вийшов з ладу через тиждень. У повідомленні про помилку вказується, що підписи не збігаються, а не те, що термін дії URL-адреси для завантаження минув. Я вносив різні зміни до свого коду, і все працювало ... доти, як усе через тиждень все не вийшло з ладу. Це тривало понад місяць розчарування.
Зробіть свій файл загальнодоступним
Ви можете встановити дозволи на ваш файл для публічного читання, як це пояснено в документації . Це можна зробити з браузера хмарного зберігання даних або з вашого сервера вузлів. Ви можете зробити один файл загальнодоступним, каталог чи всю базу даних. Ось код Вузла:
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. Ви не знайдете його в жодній документації Google, і не обіцяйте, що вона буде в майбутній версії @google-cloud. Мені подобається, firebaseStorageDownloadTokensтому що це єдиний спосіб отримати те, що я хочу, але він має «запах», який використовувати його не безпечно.
Чому немає getDownloadURL () від Node?
Як писав @Clinton, Google повинен створити file.getDownloadURL()метод у @google-cloud/storage(тобто зворотній частині вашого вузла). Я хочу завантажити файл з Google Cloud Functions і отримати URL-адресу для завантаження маркера.