Ta odpowiedź zawiera podsumowanie opcji pobierania adresu URL pobierania podczas przesyłania pliku do Google / Firebase Cloud Storage. Istnieją trzy typy adresów URL pobierania:
- podpisane adresy URL pobierania, które są tymczasowe i mają funkcje zabezpieczeń
- adresy URL pobierania tokenu, które są trwałe i mają funkcje bezpieczeństwa
- publiczne adresy URL pobierania, które są trwałe i pozbawione zabezpieczeń
Istnieją trzy sposoby uzyskania adresu URL pobierania tokena. Pozostałe dwa adresy URL pobierania mają tylko jeden sposób, aby je uzyskać.
Z konsoli Firebase Storage
Adres URL pobierania możesz uzyskać z konsoli Firebase Storage:
Adres URL pobierania wygląda następująco:
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
Pierwsza część to standardowa ścieżka do Twojego pliku. Na końcu jest token. Ten adres URL pobierania jest trwały, tj. Nie wygaśnie, chociaż można go cofnąć.
getDownloadURL () z interfejsu użytkownika
Dokumentacja mówi nam do wykorzystania getDownloadURL()
:
let url = await firebase.storage().ref('Audio/English/United_States-OED-' + i +'/' + $scope.word.word + ".mp3").getDownloadURL();
Otrzymuje ten sam adres URL pobierania, który możesz pobrać z konsoli Firebase Storage. Ta metoda jest łatwa, ale wymaga znajomości ścieżki do pliku, który w mojej aplikacji zawiera około 300 linii kodu, aby uzyskać stosunkowo prostą strukturę bazy danych. Jeśli twoja baza danych jest złożona, byłby to koszmar. Możesz przesyłać pliki z poziomu interfejsu użytkownika, ale spowoduje to ujawnienie Twoich danych uwierzytelniających każdemu, kto pobierze Twoją aplikację. Dlatego w przypadku większości projektów będziesz chciał przesłać pliki z zaplecza Node lub Google Cloud Functions, a następnie uzyskać adres URL pobierania i zapisać go w bazie danych wraz z innymi danymi o pliku.
getSignedUrl () dla tymczasowych adresów URL pobierania
getSignedUrl () jest łatwy w użyciu z zaplecza Node lub Google Cloud Functions:
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);
}
});
});
});
});
}
Podpisany adres URL pobierania wygląda następująco:
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
Podpisany adres URL ma datę ważności i długi podpis. Dokumentacja dotycząca wiersza poleceń gsutil signurl -d mówi, że podpisane adresy URL są tymczasowe: domyślny okres ważności to jedna godzina, a maksymalny okres ważności to siedem dni.
Mam zamiar ogłosić, że getSignedUrl nigdy nie mówi, że Twój podpisany adres URL wygaśnie za tydzień. Kod dokumentacji ma 3-17-2025
datę wygaśnięcia, co sugeruje, że można ustawić lata wygaśnięcia w przyszłości. Moja aplikacja działała idealnie, a tydzień później uległa awarii. Komunikat o błędzie mówił, że podpisy nie pasują, a nie że adres URL pobierania wygasł. Wprowadziłem różne zmiany w moim kodzie i wszystko działało ... aż wszystko się zawiesiło tydzień później. Trwało to ponad miesiąc frustracji.
Udostępnij plik publicznie
Możesz ustawić uprawnienia do publicznego odczytu pliku, jak wyjaśniono w dokumentacji . Można to zrobić z przeglądarki Cloud Storage lub z serwera Node. Możesz ustawić jeden plik jako publiczny, katalog lub całą bazę danych magazynu. Oto kod węzła:
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));
});
Wynik będzie wyglądał następująco w przeglądarce Cloud Storage:
Każdy może następnie użyć standardowej ścieżki do pobrania pliku:
https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/English/United_States-OED-0/system.mp3
Innym sposobem na upublicznienie pliku jest użycie metody makePublic () . Nie udało mi się to uruchomić, trudno jest poprawnie ustawić zasobnik i ścieżki plików.
Ciekawą alternatywą jest użycie list kontroli dostępu . Możesz udostępnić plik tylko użytkownikom, których umieścisz na liście, lub użyć go, authenticatedRead
aby udostępnić plik każdemu, kto jest zalogowany z konta Google. Gdyby istniała opcja „każdy, kto logował się do mojej aplikacji przy użyciu uwierzytelniania Firebase”, użyłbym tej opcji, ponieważ ograniczyłaby dostęp tylko do moich użytkowników.
Zbuduj własny adres URL pobierania za pomocą firebaseStorageDownloadTokens
W kilku odpowiedziach opisano nieudokumentowaną właściwość obiektu Google Storage firebaseStorageDownloadTokens
. Dzięki temu możesz wskazać Storage token, którego chcesz użyć. Możesz wygenerować token za pomocą uuid
modułu Node. Cztery wiersze kodu i możesz utworzyć własny adres URL pobierania, ten sam adres URL pobierania, który otrzymasz z konsoli lub getDownloadURL()
. Cztery wiersze kodu to:
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);
Oto kod w kontekście:
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));
});
To nie jest literówka - musisz zagnieździć się firebaseStorageDownloadTokens
w podwójnych warstwach metadata:
!
Doug Stevenson zwrócił uwagę, że firebaseStorageDownloadTokens
nie jest to oficjalna funkcja Google Cloud Storage. Nie znajdziesz go w żadnej dokumentacji Google i nie ma obietnic, że będzie w przyszłej wersji@google-cloud
. Lubię, firebaseStorageDownloadTokens
ponieważ jest to jedyny sposób na zdobycie tego, czego chcę, ale ma „zapach”, którego nie jest bezpieczny w użyciu.
Dlaczego nie ma metody getDownloadURL () z węzła?
Jak napisał @Clinton, Google powinien utworzyć file.getDownloadURL()
metodę w @google-cloud/storage
(tj. Zapleczu Twojego Node). Chcę przesłać plik z Google Cloud Functions i uzyskać adres URL pobierania tokena.