Después de cargar un archivo en Firebase Storage con Funciones para Firebase, me gustaría obtener la URL de descarga del archivo.
Tengo esto :
...
return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {
// Get the download url of file
});
El archivo de objeto tiene muchos parámetros. Incluso uno nombrado mediaLink
. Sin embargo, si intento acceder a este enlace, aparece este error:
Los usuarios anónimos no tienen acceso storage.objects.get al objeto ...
¿Alguien puede decirme cómo obtener la URL de descarga pública?
Gracias
Respuestas:
Deberá generar una URL firmada mediante getSignedURL a través del módulo NPM @ google-cloud / storage .
Ejemplo:
Deberá inicializar
@google-cloud/storage
con las credenciales de su cuenta de servicio, ya que las credenciales predeterminadas de la aplicación no serán suficientes.ACTUALIZACIÓN : Ahora se puede acceder al SDK de Cloud Storage a través del SDK de Firebase Admin, que actúa como un contenedor de @ google-cloud / storage. La única forma en que lo hará es si usted:
fuente
action
yexpires
?A continuación, se muestra un ejemplo sobre cómo especificar el token de descarga en la carga:
entonces llama con
La clave aquí es que hay un
metadata
objeto anidado dentro de lametadata
propiedad de la opción. EstablecerfirebaseStorageDownloadTokens
un valor uuid-v4 le indicará a Cloud Storage que lo use como su token de autenticación público.Muchas gracias a @martemorfosis
fuente
Esta respuesta resumirá las opciones para obtener la URL de descarga al cargar un archivo en Google / Firebase Cloud Storage. Hay tres tipos de URL de descarga:
Hay tres formas de obtener una URL de descarga de token. Las otras dos URL de descarga solo tienen una forma de obtenerlas.
Desde Firebase Storage Console
Puede obtener la URL de descarga desde la consola de Firebase Storage:
La URL de descarga se ve así:
La primera parte es una ruta estándar a su archivo. Al final está la ficha. Esta URL de descarga es permanente, es decir, no caducará, aunque puede revocarla.
getDownloadURL () desde la interfaz
La documentación nos dice que usemos
getDownloadURL()
:Esto obtiene la misma URL de descarga que puede obtener de su consola de Firebase Storage. Este método es fácil pero requiere que conozca la ruta a su archivo, que en mi aplicación es de aproximadamente 300 líneas de código, para una estructura de base de datos relativamente simple. Si su base de datos es compleja, esto sería una pesadilla. Y podría cargar archivos desde la interfaz, pero esto expondría sus credenciales a cualquiera que descargue su aplicación. Entonces, para la mayoría de los proyectos, querrá cargar sus archivos desde su back-end de Node o Google Cloud Functions, luego obtenga la URL de descarga y guárdela en su base de datos junto con otros datos sobre su archivo.
getSignedUrl () para URL de descarga temporal
getSignedUrl () es fácil de usar desde un back-end de Node o Google Cloud Functions:
Una URL de descarga firmada se ve así:
La URL firmada tiene una fecha de vencimiento y una firma larga. La documentación de la línea de comandos gsutil signurl -d dice que las URL firmadas son temporales: el vencimiento predeterminado es una hora y el vencimiento máximo es siete días.
Voy a despotricar aquí que getSignedUrl nunca dice que su URL firmada caducará en una semana. El código de documentación tiene
3-17-2025
como fecha de vencimiento, lo que sugiere que puede establecer los años de vencimiento en el futuro. Mi aplicación funcionó perfectamente y luego se bloqueó una semana después. El mensaje de error decía que las firmas no coincidían, no que la URL de descarga había caducado. Hice varios cambios en mi código y todo funcionó ... hasta que todo falló una semana después. Esto continuó durante más de un mes de frustración.Haga que su archivo esté disponible públicamente
Puede configurar los permisos en su archivo para lectura pública, como se explica en la documentación . Esto se puede hacer desde el navegador de almacenamiento en la nube o desde su servidor Node. Puede hacer público un archivo o un directorio o toda su base de datos de almacenamiento. Aquí está el código de nodo:
El resultado se verá así en su navegador de almacenamiento en la nube:
Cualquiera puede usar la ruta estándar para descargar su archivo:
Otra forma de hacer público un archivo es usar el método makePublic () . No he podido hacer que esto funcione, es complicado acertar las rutas del depósito y del archivo.
Una alternativa interesante es utilizar listas de control de acceso . Puede hacer que un archivo esté disponible solo para los usuarios que haya incluido en una lista, o usarlo
authenticatedRead
para que el archivo esté disponible para cualquier persona que haya iniciado sesión desde una cuenta de Google. Si hubiera una opción "cualquiera que inicie sesión en mi aplicación usando Firebase Auth", la usaría, ya que limitaría el acceso solo a mis usuarios.Cree su propia URL de descarga con firebaseStorageDownloadTokens
Varias respuestas describen una propiedad de objeto de Google Storage indocumentada
firebaseStorageDownloadTokens
. Con esto, puede decirle a Storage el token que desea usar. Puede generar un token con eluuid
módulo Node. Cuatro líneas de código y puede crear su propia URL de descarga, la misma URL de descarga que obtiene de la consola ogetDownloadURL()
. Las cuatro líneas de código son:Aquí está el código en contexto:
Eso no es un error tipográfico, ¡tienes que anidar
firebaseStorageDownloadTokens
en capas dobles demetadata:
!Doug Stevenson señaló que
firebaseStorageDownloadTokens
no es una función oficial de Google Cloud Storage. No lo encontrará en ninguna documentación de Google, y no hay ninguna promesa de que lo esté en una versión futura de@google-cloud
. Me gustafirebaseStorageDownloadTokens
porque es la única forma de obtener lo que quiero, pero tiene un "olor" que no es seguro de usar.¿Por qué No getDownloadURL () de Node?
Como escribió @Clinton, Google debería crear un
file.getDownloadURL()
método en@google-cloud/storage
(es decir, su back-end de Node). Quiero subir un archivo desde Google Cloud Functions y obtener la URL de descarga del token.fuente
@google-cloud/storage
para esto, no dudes enfirebaseStorageDownloadTokens
ya no funciona.Con los cambios recientes en la respuesta del objeto de funciones , puede obtener todo lo que necesita para "unir" la URL de descarga así:
fuente
bucket.file().upload()
? No recibo ninguna propiedad de metadatos en los datos de respuesta y no estoy seguro de cómo obtenerlosfirebaseStorageDownloadTokens
.bucket.name
, no tienes que codificarlo ni usar una var local adicionalmetadata.mediaLink
propiedad evita este problema.Si está trabajando en un proyecto de Firebase, puede crear URL firmadas en una función de Cloud sin incluir otras bibliotecas ni descargar un archivo de credenciales. Solo necesita habilitar la API de IAM y agregar un rol a su cuenta de servicio existente (ver más abajo).
Inicialice la biblioteca de administración y obtenga una referencia de archivo como lo haría normalmente:
Luego genera una URL firmada con
Asegúrese de que su cuenta de servicio de Firebase tenga permisos suficientes para ejecutar este
Con una configuración básica de Firebase, la primera vez que ejecute el código anterior, obtendrá un error La API de administración de identidad y acceso (IAM) no se ha utilizado antes en el proyecto XXXXXX o está deshabilitada. . Si sigue el enlace del mensaje de error y habilita la API de IAM, obtendrá otro error: Se requiere el permiso iam.serviceAccounts.signBlob para realizar esta operación en la cuenta de servicio my-service-account . Agregar el rol de Creador de tokens soluciona este segundo problema de permisos.
fuente
Un método que estoy usando con éxito es establecer un valor UUID v4 en una clave nombrada
firebaseStorageDownloadTokens
en los metadatos del archivo después de que termine de cargarse y luego ensamblar la URL de descarga siguiendo la estructura que usa Firebase para generar estas URL, por ejemplo:No sé cuánto "seguro" es usar este método (dado que Firebase podría cambiar la forma en que genera las URL de descarga en el futuro), pero es fácil de implementar.
fuente
Para aquellos que se preguntan dónde debería ir el archivo serviceAccountKey.json del SDK de Firebase Admin. Simplemente colóquelo en la carpeta de funciones e impleméntelo como de costumbre.
Todavía me desconcierta por qué no podemos simplemente obtener la URL de descarga de los metadatos como lo hacemos en el SDK de Javascript. No es deseable generar una URL que eventualmente caduque y guardarla en la base de datos.
fuente
Sugiero usar la opción
predefinedAcl: 'publicRead'
al cargar un archivo con Cloud Storage NodeJS 1.6.xo +:Entonces, obtener la URL pública es tan simple como:
fuente
Lo siento, pero no puedo publicar un comentario a su pregunta anterior debido a la falta de reputación, por lo que la incluiré en esta respuesta.
Haga lo que se indicó anteriormente generando una URL firmada, pero en lugar de usar service-account.json, creo que debe usar serviceAccountKey.json que puede generar en (reemplace YOURPROJECTID en consecuencia)
https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk
Ejemplo:
fuente
No puedo comentar sobre la respuesta que dio James Daniels, pero creo que es muy importante leer esto.
Dar una URL firmada, como lo hizo él, parece en muchos casos bastante malo y posiblemente peligroso. . De acuerdo con la documentación de Firebase, la URL firmada caduca después de un tiempo, por lo que agregarla a su base de datos conducirá a una URL vacía después de un cierto período de tiempo.
Es posible que no se haya entendido bien la Documentación allí y que la URL firmada no caduque, lo que tendría algunos problemas de seguridad como resultado. La clave parece ser la misma para todos los archivos cargados. Esto significa que una vez que obtenga la URL de un archivo, alguien podría acceder fácilmente a los archivos a los que no se supone que acceda, simplemente conociendo sus nombres.
Si entendí mal eso, entonces me gustaría ser corregido. De lo contrario, probablemente alguien debería actualizar la solución mencionada anteriormente. Si puedo estar equivocado allí
fuente
Esto es lo que uso actualmente, es simple y funciona a la perfección.
No necesitas hacer nada con Google Cloud. Funciona de inmediato con Firebase.
EDITAR: Mismo ejemplo, pero con carga:
actualizar:
no es necesario realizar dos llamadas diferentes en el método de carga para obtener los metadatos:
fuente
Tuve el mismo problema, sin embargo, estaba mirando el código del ejemplo de la función firebase en lugar del README. Y las respuestas en este hilo tampoco ayudaron ...
Puede evitar pasar el archivo de configuración haciendo lo siguiente:
fuente: función de automática de miniaturas README
Su función para el motor de aplicaciones debería verse así:
fuente
Si usa el valor de listas de control de acceso predefinido de 'publicRead', puede cargar el archivo y acceder a él con una estructura de URL muy simple:
Luego puede construir la URL así:
fuente
Esto funciona si solo necesita un archivo público con una URL simple. Tenga en cuenta que esto puede anular sus reglas de almacenamiento de Firebase.
fuente
Para aquellos que usan Firebase SDK y
admin.initializeApp
:1 - Genere una clave privada y colóquela en la carpeta / functions.
2 - Configure su código de la siguiente manera:
Documentación
El intento / captura es porque estoy usando un index.js que importa otros archivos y crea una función para cada archivo. Si está utilizando un solo archivo index.js con todas las funciones, debería estar de acuerdo con
admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));
.fuente
A partir de firebase 6.0.0, pude acceder al almacenamiento directamente con el administrador de esta manera:
Así que no necesité agregar una cuenta de servicio. Luego, configurar el UUID como se mencionó anteriormente funcionó para obtener la URL de la base de fuego.
fuente
Esto es lo mejor que se me ocurrió. Es redundante, pero la única solución razonable que funcionó para mí.
fuente
Sin
signedURL()
usarmakePublic()
fuente
la respuesta por https://stackoverflow.com/users/269447/laurent funciona mejor
fuente
Si recibe un error:
prueba esto:
fuente
Ya publico mi ans ... en la siguiente URL donde puede obtener el código completo con la solución
¿Cómo subo una imagen (cadena) codificada en base64 directamente a un depósito de Google Cloud Storage con Node.js?
fuente