Ця відповідь підсумовує варіанти отримання 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-адресу для завантаження маркера.