Questa risposta riepilogherà le opzioni per ottenere l'URL di download durante il caricamento di un file su Google / Firebase Cloud Storage. Esistono tre tipi di URL di download:
- URL di download firmati, che sono temporanei e hanno funzioni di sicurezza
- URL di download di token, che sono persistenti e dispongono di funzionalità di sicurezza
- URL di download pubblici, persistenti e privi di sicurezza
Esistono tre modi per ottenere un URL di download del token. Gli altri due URL di download hanno un solo modo per ottenerli.
Dalla Firebase Storage Console
Puoi ottenere l'URL di download dalla console di Firebase Storage:
L'URL di download è simile a questo:
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
La prima parte è un percorso standard del file. Alla fine c'è il gettone. Questo URL di download è permanente, ovvero non scadrà, sebbene tu possa revocarlo.
getDownloadURL () dal front-end
La documentazione ci dice di usare getDownloadURL()
:
let url = await firebase.storage().ref('Audio/English/United_States-OED-' + i +'/' + $scope.word.word + ".mp3").getDownloadURL();
Ottiene lo stesso URL di download che puoi ottenere dalla tua console di archiviazione Firebase. Questo metodo è semplice ma richiede che tu conosca il percorso del tuo file, che nella mia app è di circa 300 righe di codice, per una struttura di database relativamente semplice. Se il tuo database è complesso, questo sarebbe un incubo. E potresti caricare file dal front-end, ma questo esporrebbe le tue credenziali a chiunque scarichi la tua app. Quindi, per la maggior parte dei progetti, ti consigliamo di caricare i tuoi file dal back-end di Node o Google Cloud Functions, quindi ottenere l'URL di download e salvarlo nel database insieme ad altri dati sul file.
getSignedUrl () per gli URL di download temporanei
getSignedUrl () è facile da usare da un back-end di nodi o da 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);
}
});
});
});
});
}
Un URL di download firmato ha questo aspetto:
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
L'URL firmato ha una data di scadenza e una firma lunga. La documentazione per la riga di comando gsutil signurl -d dice che gli URL firmati sono temporanei: la scadenza predefinita è un'ora e la scadenza massima è sette giorni.
Ho intenzione di sbraitare qui che getSignedUrl non dice mai che il tuo URL firmato scadrà tra una settimana. Il codice della documentazione ha 3-17-2025
come data di scadenza, suggerendo che è possibile impostare gli anni di scadenza in futuro. La mia app ha funzionato perfettamente e poi si è bloccata una settimana dopo. Il messaggio di errore diceva che le firme non corrispondevano, non che l'URL di download era scaduto. Ho apportato varie modifiche al mio codice e tutto ha funzionato ... fino a quando non è andato in crash una settimana dopo. Questo è andato avanti per più di un mese di frustrazione.
Rendi il tuo file disponibile pubblicamente
È possibile impostare i permessi sul file in lettura pubblica, come spiegato nella documentazione . Questo può essere fatto dal browser Cloud Storage o dal tuo server Node. È possibile rendere pubblico un file o una directory o l'intero database di archiviazione. Ecco il codice del nodo:
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));
});
Il risultato sarà simile a questo nel tuo browser Cloud Storage:
Chiunque può quindi utilizzare il percorso standard per scaricare il file:
https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/English/United_States-OED-0/system.mp3
Un altro modo per rendere pubblico un file è usare il metodo makePublic () . Non sono riuscito a farlo funzionare, è difficile ottenere il bucket e i percorsi dei file corretti.
Un'alternativa interessante è usare gli elenchi di controllo degli accessi . Puoi rendere un file disponibile solo per gli utenti che hai inserito in un elenco o utilizzarlo authenticatedRead
per rendere il file disponibile a chiunque abbia effettuato l'accesso da un account Google. Se ci fosse un'opzione "chiunque abbia effettuato l'accesso alla mia app utilizzando Firebase Auth", la userei, poiché limiterebbe l'accesso solo ai miei utenti.
Crea il tuo URL di download con firebaseStorageDownloadTokens
Diverse risposte descrivono una proprietà di un oggetto Google Storage non documentata firebaseStorageDownloadTokens
. Con questo puoi dire a Storage il token che desideri utilizzare. Puoi generare un token con il uuid
modulo Node. Quattro righe di codice e puoi creare il tuo URL di download, lo stesso URL di download che ottieni dalla console o getDownloadURL()
. Le quattro righe di codice sono:
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);
Ecco il codice nel contesto:
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));
});
Non è un errore di battitura: devi nidificare firebaseStorageDownloadTokens
in doppi strati dimetadata:
!
Doug Stevenson ha sottolineato che firebaseStorageDownloadTokens
non è una funzione ufficiale di Google Cloud Storage. Non lo troverai in nessuna documentazione di Google e non ci sono promesse che sarà nella versione futura di @google-cloud
. Mi piace firebaseStorageDownloadTokens
perché è l'unico modo per ottenere quello che voglio, ma ha un "odore" che non è sicuro da usare.
Perché nessun getDownloadURL () da Node?
Come ha scritto @Clinton, Google dovrebbe creare un file.getDownloadURL()
metodo in @google-cloud/storage
(cioè, il tuo back-end Node). Voglio caricare un file da Google Cloud Functions e ottenere l'URL di download del token.