Esta resposta resumirá as opções para obter o URL de download ao enviar um arquivo para o Google / Firebase Cloud Storage. Existem três tipos de URLS de download:
- URLs de download assinados, que são temporários e possuem recursos de segurança
- URLs de download de tokens, que são persistentes e possuem recursos de segurança
- URLs de download público, que são persistentes e carecem de segurança
Existem três maneiras de obter um URL de download de token. Os outros dois URLs de download têm apenas uma maneira de obtê-los.
No Firebase Storage Console
Você pode obter o URL de download no console do Firebase Storage:
O URL de download é parecido com este:
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
A primeira parte é um caminho padrão para o seu arquivo. No final está o token. Este URL de download é permanente, ou seja, não irá expirar, embora você possa revogá-lo.
getDownloadURL () no front end
A documentação nos diz para usar getDownloadURL()
:
let url = await firebase.storage().ref('Audio/English/United_States-OED-' + i +'/' + $scope.word.word + ".mp3").getDownloadURL();
Obtém o mesmo URL de download que você pode obter no console do Firebase Storage. Esse método é fácil, mas requer que você saiba o caminho para o seu arquivo, que em meu aplicativo tem cerca de 300 linhas de código, para uma estrutura de banco de dados relativamente simples. Se o seu banco de dados for complexo, isso seria um pesadelo. E você pode fazer upload de arquivos do front end, mas isso exporia suas credenciais para qualquer pessoa que baixasse seu aplicativo. Portanto, para a maioria dos projetos, você desejará fazer upload de seus arquivos do back-end do Node ou do Google Cloud Functions e, em seguida, obter o URL de download e salvá-lo em seu banco de dados junto com outros dados sobre seu arquivo.
getSignedUrl () para URLs de download temporário
getSignedUrl () é fácil de usar em um back end do Node ou no 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);
}
});
});
});
});
}
Um URL de download assinado tem a seguinte aparência:
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
O URL assinado tem uma data de validade e assinatura longa. A documentação da linha de comando gsutil signurl -d diz que os URLs assinados são temporários: a expiração padrão é de uma hora e a expiração máxima é de sete dias.
Vou reclamar aqui que getSignedUrl nunca diz que seu URL assinado irá expirar em uma semana. O código da documentação tem 3-17-2025
como data de validade, sugerindo que você pode definir os anos de expiração no futuro. Meu aplicativo funcionou perfeitamente e travou uma semana depois. A mensagem de erro dizia que as assinaturas não correspondiam, não que o URL de download havia expirado. Fiz várias alterações no meu código e tudo funcionou ... até que tudo travou uma semana depois. Isso durou mais de um mês de frustração.
Disponibilize seu arquivo publicamente
Você pode definir as permissões em seu arquivo para leitura pública, conforme explicado na documentação . Isso pode ser feito no navegador do Cloud Storage ou no servidor Node. Você pode tornar um arquivo público ou um diretório ou todo o banco de dados do Storage. Aqui está o código do Node:
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));
});
O resultado será parecido com o seguinte no navegador do Cloud Storage:
Qualquer pessoa pode usar o caminho padrão para fazer o download do seu arquivo:
https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/English/United_States-OED-0/system.mp3
Outra maneira de tornar um arquivo público é usar o método makePublic () . Eu não consegui fazer isso funcionar, é complicado acertar os caminhos do intervalo e do arquivo.
Uma alternativa interessante é usar listas de controle de acesso . Você pode disponibilizar um arquivo apenas para usuários que você colocou em uma lista ou usar authenticatedRead
para disponibilizar o arquivo para qualquer pessoa que esteja conectada a uma conta do Google. Se houvesse uma opção "qualquer pessoa que se conectou ao meu aplicativo usando Firebase Auth", eu a usaria, pois limitaria o acesso apenas aos meus usuários.
Crie seu próprio URL de download com firebaseStorageDownloadTokens
Várias respostas descrevem uma propriedade de objeto do Google Storage não documentada firebaseStorageDownloadTokens
. Com isso, você pode informar ao Storage o token que deseja usar. Você pode gerar um token com o uuid
módulo Node. Quatro linhas de código e você pode construir seu próprio URL de download, o mesmo URL de download que obtém no console ou getDownloadURL()
. As quatro linhas de código são:
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);
Aqui está o código em contexto:
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));
});
Isso não é um erro de digitação - você deve aninhar firebaseStorageDownloadTokens
em camadas duplas de metadata:
!
Doug Stevenson apontou que firebaseStorageDownloadTokens
não é um recurso oficial do Google Cloud Storage. Você não o encontrará em nenhuma documentação do Google e não há promessa de que será em uma versão futura do @google-cloud
. Gosto firebaseStorageDownloadTokens
porque é a única maneira de conseguir o que quero, mas tem um "cheiro" que não é seguro usar.
Por que não getDownloadURL () do Node?
Como escreveu @Clinton, o Google deve criar um file.getDownloadURL()
método em @google-cloud/storage
(ou seja, seu back end do Node). Quero fazer upload de um arquivo do Google Cloud Functions e obter o URL de download do token.