Depois de fazer upload de um arquivo no Firebase storage com funções para Firebase, gostaria de obter o URL de download do arquivo.
Eu tenho isto :
...
return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {
// Get the download url of file
});
O arquivo objeto tem muitos parâmetros. Mesmo um nomeado mediaLink
. No entanto, se tento acessar este link, recebo este erro:
Usuários anônimos não têm acesso storage.objects.get ao objeto ...
Alguém pode me dizer como obter o URL público de download?
Obrigado
Respostas:
Você precisará gerar um URL assinado usando getSignedURL por meio do módulo NPM @ google-cloud / storage .
Exemplo:
Você precisará inicializar
@google-cloud/storage
com suas credenciais de conta de serviço, pois as credenciais padrão do aplicativo não serão suficientes.ATUALIZAÇÃO : o Cloud Storage SDK agora pode ser acessado por meio do Firebase Admin SDK, que atua como um wrapper em torno de @ google-cloud / storage. A única maneira é se você:
fonte
action
eexpires
?Aqui está um exemplo de como especificar o token de download no upload:
então ligue com
O principal aqui é que há um
metadata
objeto aninhado nametadata
propriedade option. DefinirfirebaseStorageDownloadTokens
como um valor uuid-v4 dirá ao Cloud Storage para usá-lo como seu token de autenticação público.Muito obrigado a @martemorfosis
fonte
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:
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:
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()
: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:
Um URL de download assinado tem a seguinte aparência:
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:
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:
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 ouuid
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 ougetDownloadURL()
. As quatro linhas de código são:Aqui está o código em contexto:
Isso não é um erro de digitação - você deve aninhar
firebaseStorageDownloadTokens
em camadas duplas demetadata:
!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
. GostofirebaseStorageDownloadTokens
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.fonte
@google-cloud/storage
para isso, fiquefirebaseStorageDownloadTokens
não funciona mais.Com as mudanças recentes na resposta do objeto de funções, você pode obter tudo o que precisa para "costurar" o URL de download, como:
fonte
bucket.file().upload()
? Não recebo nenhuma propriedade de metadados nos dados de resposta e não tenho certeza de como obtê-losfirebaseStorageDownloadTokens
.bucket.name
, você não precisa codificá-lo ou usar uma var local extrametadata.mediaLink
propriedade evita esse problema.Se você estiver trabalhando em um projeto do Firebase, poderá criar URLs assinados em um Cloud Function sem incluir outras bibliotecas ou baixar um arquivo de credenciais. Você só precisa habilitar a API IAM e adicionar uma função à sua conta de serviço existente (veja abaixo).
Inicialize a biblioteca de administração e obtenha uma referência de arquivo como faria normalmente:
Você então gera um URL assinado com
Certifique-se de que sua conta de serviço do Firebase tenha permissões suficientes para executar este
Com uma configuração do Firebase vanilla, na primeira vez que executar o código acima, você receberá um erro A API Identity and Access Management (IAM) não foi usada no projeto XXXXXX antes ou está desativada. . Se você seguir o link na mensagem de erro e ativar a API IAM, receberá outro erro: Permission iam.serviceAccounts.signBlob é necessário para executar esta operação na conta de serviço my-service-account . Adicionar a função Token Creator corrige esse segundo problema de permissão.
fonte
Um método que estou usando com sucesso é definir um valor UUID v4 para uma chave nomeada
firebaseStorageDownloadTokens
nos metadados do arquivo após terminar o upload e, em seguida, montar o URL de download eu mesmo seguindo a estrutura que o Firebase usa para gerar esses URLs, por exemplo:Não sei o quanto "seguro" é usar esse método (visto que o Firebase pode mudar a forma como gera os URLs de download no futuro), mas é fácil de implementar.
fonte
Para aqueles que estão se perguntando onde o arquivo serviceAccountKey.json do SDK Admin do Firebase deve ir. Basta colocá-lo na pasta de funções e implantar normalmente.
Ainda me confunde por que não podemos simplesmente obter o URL de download dos metadados como fazemos no SDK Javascript. Não é desejável gerar uma url que irá expirar e salvá-la no banco de dados.
fonte
Eu sugiro usar a opção
predefinedAcl: 'publicRead'
ao enviar um arquivo com Cloud Storage NodeJS 1.6.x ou +:Então, obter o URL público é tão simples como:
fonte
Desculpe, mas não posso postar um comentário para sua pergunta acima por causa da falta de reputação, então vou incluí-lo nesta resposta.
Faça conforme indicado acima, gerando um Url assinado, mas em vez de usar o service-account.json, acho que você deve usar o serviceAccountKey.json que pode ser gerado em (substitua YOURPROJECTID de acordo)
https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk
Exemplo:
fonte
Não posso comentar a resposta que James Daniels deu, mas acho muito importante ler isso.
Distribuir uma URL assinada como ele fez parece, em muitos casos, muito ruim e possivelmente perigoso . De acordo com a documentação do Firebase, o url assinado expira depois de algum tempo, portanto, adicioná-lo ao seu banco de dados levará a um url vazio após um determinado período
Pode ser que a documentação não tenha entendido bem e a url assinada não expire, o que causaria alguns problemas de segurança. A chave parece ser a mesma para todos os arquivos carregados. Isso significa que, uma vez que você obteve o url de um arquivo, alguém poderia acessar facilmente os arquivos que não deveria acessar, apenas por saber seus nomes.
Se eu não entendesse isso, gostaria de ser corrigido. Caso contrário, alguém provavelmente deveria atualizar a solução nomeada acima. Se eu posso estar errado lá
fonte
É o que eu uso atualmente, é simples e funciona perfeitamente.
Você não precisa fazer nada com o Google Cloud. Funciona imediatamente com o Firebase.
EDIT: Mesmo exemplo, mas com upload:
atualizar:
não há necessidade de fazer duas chamadas diferentes no método de upload para obter os metadados:
fonte
Eu tive o mesmo problema, no entanto, estava olhando para o código do exemplo da função firebase em vez do README. E as respostas neste tópico também não ajudaram ...
Você pode evitar passar o arquivo de configuração fazendo o seguinte:
fonte: Função de geração automática de miniaturas README
Sua função para o App Engine deve ser assim:
fonte
Se você usar o valor predefinido de listas de controle de acesso de 'publicRead', poderá fazer upload do arquivo e acessá-lo com uma estrutura de url muito simples:
Você pode então construir o url assim:
fonte
Isso funciona se você precisar apenas de um arquivo público com uma URL simples. Observe que isso pode anular suas regras de armazenamento do Firebase.
fonte
Para aqueles que usam Firebase SDK e
admin.initializeApp
:1 - Gere uma Chave Privada e coloque na pasta / funções.
2 - Configure seu código da seguinte maneira:
Documentação
O try / catch é porque estou usando um index.js que importa outros arquivos e cria uma função para cada arquivo. Se você estiver usando um único arquivo index.js com todas as funções, não terá problemas
admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));
.fonte
A partir do Firebase 6.0.0, consegui acessar o armazenamento diretamente com o administrador desta forma:
Portanto, não precisei adicionar uma conta de serviço. Então, definir o UUID conforme mencionado acima funcionou para obter o url do firebase.
fonte
Este é o melhor que descobri. É redundante, mas a única solução razoável que funcionou para mim.
fonte
Sem
signedURL()
usarmakePublic()
fonte
responder por https://stackoverflow.com/users/269447/laurent funciona melhor
fonte
Se você estiver recebendo um erro:
tente isto:
fonte
Eu já postei minha ans ... na URL abaixo Onde você pode obter o código completo com a solução
Como faço o upload de uma imagem codificada em base64 (string) diretamente para um intervalo do Google Cloud Storage usando Node.js?
fonte