¿Cómo obtener una lista de todos los archivos en Cloud Storage en una aplicación de Firebase?

101

Estoy trabajando en subir imágenes, todo funciona muy bien, pero tengo 100 imágenes y me gustaría mostrarlas todas en mi View, ya que obtengo la lista completa de las imágenes en una carpeta, no encuentro ninguna API para esto trabajo.

Luis Ruiz Figueroa
fuente
¿Puedes publicar una solución de código completa?
ISS

Respuestas:

92

Desde la versión 6.1 de Firebase SDK para JavaScript , la versión 6.4 de iOS y la versión 18.1 de Android tienen un método para enumerar archivos.

La documentación es un poco escasa hasta ahora, por lo que recomiendo consultar la respuesta de Rosário para obtener más detalles.


Respuesta anterior, ya que este enfoque todavía puede ser útil a veces:

Actualmente, no hay una llamada a la API en el SDK de Firebase para enumerar todos los archivos en una carpeta de Cloud Storage desde una aplicación. Si necesita dicha funcionalidad, debe almacenar los metadatos de los archivos (como las URL de descarga) en un lugar donde pueda enumerarlos. La base de datos en tiempo real Firebase y Nube Firestore son perfectos para esto y le permite compartir fácilmente también las direcciones URL con los demás.

Puede encontrar una buena (pero algo complicada) muestra de esto en nuestra aplicación de muestra FriendlyPix . El código relevante para la versión web está aquí , pero también hay versiones para iOS y Android.

Frank van Puffelen
fuente
8
¿Vas a implementar esto en Firebase?
Muelle
55
Si necesito mantener las URL de todos mis archivos de Storage en Realtime Database, ¿cuál es el propósito de tener una jerarquía de carpetas en Storage? Todos los archivos, que tienen un nombre único, se pueden almacenar en el mismo nivel, ¡sin necesidad de carpetas! ya ves, eso es una contradicción !!! Básicamente, la razón principal detrás de la jerarquía de carpetas son las consultas con comodines sin conocimiento previo de lo que tiene en una carpeta, que no proporciona de manera razonable.
abedfar
7
Firebase Storage se basa en Google Cloud Storage, que hace precisamente lo que dices: almacena todos los objetos en una larga lista. Firebase Storage modela una jerarquía además de eso, ciertamente como una abstracción con fugas. Las razones más comunes para usar la carpeta en Firebase Storage son la separación lógica de datos y la elaboración de reglas de seguridad basadas en la estructura de la carpeta.
Frank van Puffelen
8
¿Qué sucede si se pierde la conexión del usuario después de la carga y antes de guardar downloadUrl en la base de datos? ¿Cómo descubrimos los archivos existentes en una carpeta en ese caso?
Oswaldo
10
Qué te parece ahora ? ¿Hay alguna API directa para esto en 2018?
Díaz diaz
46

A partir de mayo de 2019, la versión 6.1.0 del SDK de Firebase para Cloud Storage ahora admite la lista de todos los objetos de un depósito. Simplemente necesita llamar listAll()a Reference:

    // Since you mentioned your images are in a folder,
    // we'll create a Reference to that folder:
    var storageRef = firebase.storage().ref("your_folder");


    // Now we get the references of these images
    storageRef.listAll().then(function(result) {
      result.items.forEach(function(imageRef) {
        // And finally display them
        displayImage(imageRef);
      });
    }).catch(function(error) {
      // Handle any errors
    });

    function displayImage(imageRef) {
      imageRef.getDownloadURL().then(function(url) {
        // TODO: Display the image on the UI
      }).catch(function(error) {
        // Handle any errors
      });
    }

Tenga en cuenta que para usar esta función, debe optar por la versión 2 de las Reglas de seguridad , lo que se puede hacer haciendo rules_version = '2';la primera línea de sus reglas de seguridad:

    rules_version = '2';
    service firebase.storage {
      match /b/{bucket}/o {
        match /{allPaths=**} {

Recomiendo consultar los documentos para obtener más referencias.

Además, de acuerdo con la configuración , en el Paso 5, este script no está permitido Node.jsya require("firebase/app");que no regresará firebase.storage()como una función. Esto solo se logra usando import * as firebase from 'firebase/app';.

Rosário Pereira Fernandes
fuente
¿
Qué
@azheen Supongo que estás usando Flutter. Desafortunadamente, esto aún no está disponible en flutterfire. Puedes seguirlo en este tema
Rosário Pereira Fernandes
33

Desde marzo de 2017: con la incorporación de Firebase Cloud Functions y la integración más profunda de Firebase con Google Cloud, esto ahora es posible.

Con Cloud Functions puedes usar el paquete Google Cloud Node para hacer épicas operaciones en Cloud Storage. A continuación, se muestra un ejemplo que obtiene todas las URL de archivo en una matriz desde Cloud Storage. Esta función se activará cada vez que se guarde algo en el almacenamiento en la nube de Google.

Nota 1 : Esta es una operación bastante costosa desde el punto de vista computacional, ya que tiene que recorrer todos los archivos en un depósito / carpeta.

Nota 2 : escribí esto solo como un ejemplo, sin poner muchos detalles en las promesas, etc. Solo para dar una idea.

const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();

// let's trigger this function with a file upload to google cloud storage

exports.fileUploaded = functions.storage.object().onChange(event => {

  const object = event.data; // the object that was just uploaded
  const bucket = gcs.bucket(object.bucket);
  const signedUrlConfig = { action: 'read', expires: '03-17-2025' }; // this is a signed url configuration object

  var fileURLs = []; // array to hold all file urls 

  // this is just for the sake of this example. Ideally you should get the path from the object that is uploaded :)
  const folderPath = "a/path/you/want/its/folder/size/calculated";

  bucket.getFiles({ prefix: folderPath }, function(err, files) {
    // files = array of file objects
    // not the contents of these files, we're not downloading the files. 

    files.forEach(function(file) {
      file.getSignedUrl(signedUrlConfig, function(err, fileURL) {
        console.log(fileURL);
        fileURLs.push(fileURL);
      });
    });

  });

});

Espero que esto les dé una idea general. Para obtener mejores ejemplos de funciones en la nube, consulte el repositorio de Github de Google lleno de muestras de Cloud Functions para Firebase . Consulte también la documentación de la API de Google Cloud Node

johnozbay
fuente
35
Esto es demasiado estúpido para que Firebase no solo agregue esta API al SDK de Firebase
Thaina
4
@Thaina Creo que tiene que ver con la escala. Tienen que pensar no solo en aplicaciones pequeñas, sino también en gigantes. ¿Qué pasa si una ruta tiene miles de archivos? Esta operación consumiría mucha potencia informática y tendría que hacer referencia a una base de datos para cada llamada aparentemente inocente y simple. Cuanto más me he adentrado en el uso de firebase a escala, mejor entiendo por qué se hicieron ciertos compromisos.
johnozbay
1
En esta API de gcs también tiene límite y paginación, entonces es responsabilidad del consumidor de la API conocer el riesgo e intentar elegir un método que pueda escalar. Pero ser sobreprotector para cortar nuestra opción no es una buena decisión. Pueden cobrar por cargas pesadas si realmente cuestan
Thaina
1
esta debería ser la mejor respuesta! Gracias por el aviso. Actualmente, la sintaxis difiere de su ejemplo. En lugar de enviar una devolución de llamada como parámetro, debe encadenar una .thencomo esta:this.bucket .getFiles({ prefix: 'path/to/directory' }) .then((arr) => {})
JP Lew
1
@JPLew De nada :) Con respecto a la sintaxis, devuelven una promesa solo si se excluye la devolución de llamada. Por lo que es seguro usar el que prefiera. Vea el ejemplo aquí: cloud.google.com/nodejs/docs/reference/storage/1.3.x/…
johnozbay
20

Como no hay ningún idioma en la lista, responderé esto en Swift. Recomendamos encarecidamente usar Firebase Storage y Firebase Realtime Database juntos para lograr listas de descargas:

Compartido:

// Firebase services
var database: FIRDatabase!
var storage: FIRStorage!
...
// Initialize Database, Auth, Storage
database = FIRDatabase.database()
storage = FIRStorage.storage()
...
// Initialize an array for your pictures
var picArray: [UIImage]()

Subir:

let fileData = NSData() // get data...
let storageRef = storage.reference().child("myFiles/myFile")
storageRef.putData(fileData).observeStatus(.Success) { (snapshot) in
  // When the image has successfully uploaded, we get it's download URL
  let downloadURL = snapshot.metadata?.downloadURL()?.absoluteString
  // Write the download URL to the Realtime Database
  let dbRef = database.reference().child("myFiles/myFile")
  dbRef.setValue(downloadURL)
}

Descargar:

let dbRef = database.reference().child("myFiles")
dbRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in
  // Get download URL from snapshot
  let downloadURL = snapshot.value() as! String
  // Create a storage reference from the URL
  let storageRef = storage.referenceFromURL(downloadURL)
  // Download the data, assuming a max size of 1MB (you can change this as necessary)
  storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
    // Create a UIImage, add it to the array
    let pic = UIImage(data: data)
    picArray.append(pic)
  })
})

Para obtener más información, consulte Zero to App: Develop with Firebase , y su código fuente asociado , para ver un ejemplo práctico de cómo hacer esto.

Mike McDonald
fuente
3
Pero, ¿cómo obtengo el mismo resultado con Cloud Firestore?)
Max Kraev
5

Una solución puede ser crear un archivo (es decir, list.txt) sin nada dentro, en este archivo puede configurar los metadatos personalizados (es decir, un Mapa <Cadena, Cadena>) con la lista de todas las URL del archivo.
Entonces, si necesita descargar todos los archivos en un fodler, primero descargue los metadatos del archivo list.txt, luego recorra los datos personalizados y descargue todos los archivos con las URL en el mapa.

Andrea
fuente
4
Sí, esta es una solución, pero no puede manejar escrituras simultáneas en un solo
list.txt
5

También encontré este problema cuando estaba trabajando en mi proyecto. Realmente deseo que proporcionen un método de API final. De todos modos, así es como lo hice: cuando esté cargando una imagen en el almacenamiento de Firebase, cree un Objeto y páselo a la base de datos de Firebase al mismo tiempo. Este objeto contiene el URI de descarga de la imagen.

trailsRef.putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            Uri downloadUri = taskSnapshot.getDownloadUrl();
            DatabaseReference myRef = database.getReference().child("trails").child(trail.getUnique_id()).push();
            Image img = new Image(trail.getUnique_id(), downloadUri.toString());
            myRef.setValue(img);
        }
    });

Más tarde, cuando desee descargar imágenes de una carpeta, simplemente recorra los archivos de esa carpeta. Esta carpeta tiene el mismo nombre que la "carpeta" en el almacenamiento de Firebase, pero puede asignarles el nombre que desee. Los pongo en hilo separado.

 @Override
protected List<Image> doInBackground(Trail... params) {

    String trialId = params[0].getUnique_id();
    mDatabase = FirebaseDatabase.getInstance().getReference();
    mDatabase.child("trails").child(trialId).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            images = new ArrayList<>();
            Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
            while (iter.hasNext()) {
                Image img = iter.next().getValue(Image.class);
                images.add(img);
            }
            isFinished = true;
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

Ahora que tengo una lista de objetos que contienen los URI de cada imagen, puedo hacer lo que quiera con ellos. Para cargarlos en imageView, creé otro hilo.

    @Override
protected List<Bitmap> doInBackground(List<Image>... params) {

    List<Bitmap> bitmaps = new ArrayList<>();

    for (int i = 0; i < params[0].size(); i++) {
        try {
            URL url = new URL(params[0].get(i).getImgUrl());
            Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            bitmaps.add(bmp);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return bitmaps;
}

Esto devuelve una lista de Bitmap, cuando termina, simplemente los adjunto a ImageView en la actividad principal. Los métodos siguientes son @Override porque he creado interfaces y escucho la finalización en otros hilos.

    @Override
public void processFinishForBitmap(List<Bitmap> bitmaps) {
    List<ImageView> imageViews = new ArrayList<>();
    View v;
    for (int i = 0; i < bitmaps.size(); i++) {
        v = mInflater.inflate(R.layout.gallery_item, mGallery, false);
        imageViews.add((ImageView) v.findViewById(R.id.id_index_gallery_item_image));
        imageViews.get(i).setImageBitmap(bitmaps.get(i));
        mGallery.addView(v);
    }
}

Tenga en cuenta que primero tengo que esperar a que se devuelva List Image y luego llamar al hilo para que funcione en List Bitmap. En este caso, Image contiene el URI.

    @Override
public void processFinish(List<Image> results) {
    Log.e(TAG, "get back " + results.size());

    LoadImageFromUrlTask loadImageFromUrlTask =  new LoadImageFromUrlTask();
    loadImageFromUrlTask.delegate = this;
    loadImageFromUrlTask.execute(results);
}

Ojalá alguien lo encuentre útil. También servirá como una línea de gremio para mí en el futuro.

Tao
fuente
5

Una forma más de agregar la imagen a la base de datos mediante la función de nube para realizar un seguimiento de cada imagen cargada y almacenarla en la base de datos.

exports.fileUploaded = functions.storage.object().onChange(event => {

    const object = event.data; // the object that was just uploaded
    const contentType = event.data.contentType; // This is the image Mimme type\

    // Exit if this is triggered on a file that is not an image.
    if (!contentType.startsWith('image/')) {
        console.log('This is not an image.');
        return null;
    }

    // Get the Signed URLs for the thumbnail and original image.
    const config = {
        action: 'read',
        expires: '03-01-2500'
    };

    const bucket = gcs.bucket(event.data.bucket);
    const filePath = event.data.name;
    const file = bucket.file(filePath);

    file.getSignedUrl(config, function(err, fileURL) {
        console.log(fileURL);
        admin.database().ref('images').push({
            src: fileURL
        });
    });
});

Código completo aquí: https://gist.github.com/bossly/fb03686f2cb1699c2717a0359880cf84

Oleg Baidalka
fuente
5

Para el nodo js, ​​usé este código

const Storage = require('@google-cloud/storage');
const storage = new Storage({projectId: 'PROJECT_ID', keyFilename: 'D:\\keyFileName.json'});
const bucket = storage.bucket('project.appspot.com'); //gs://project.appspot.com
bucket.getFiles().then(results => {
    const files = results[0];
    console.log('Total files:', files.length);
    files.forEach(file => {
      file.download({destination: `D:\\${file}`}).catch(error => console.log('Error: ', error))
    });
}).catch(err => {
    console.error('ERROR:', err);
  });
tuananh
fuente
¡¡Me acabas de salvar el día !!
hugo blanc
4

Puede enumerar archivos en un directorio de almacenamiento de base de fuego mediante el método listAll (). Para utilizar este método, debe implementar esta versión de firebase storage. 'com.google.firebase: firebase-storage: 18.1.1'

https://firebase.google.com/docs/storage/android/list-files

Tenga en cuenta que actualice las Reglas de seguridad a la versión 2.

Yonghwan Shin
fuente
3

En realidad, esto es posible, pero solo con una API de Google Cloud en lugar de una de Firebase. Esto se debe a que un almacenamiento de Firebase es un depósito de almacenamiento de Google Cloud al que se puede acceder fácilmente con las API de Google Cloud, sin embargo, debe usar OAuth para la autenticación en lugar del de Firebase.

Zen M
fuente
3

Enfrenté el mismo problema, el mío es aún más complicado.

El administrador cargará archivos de audio y pdf en el almacenamiento:

  • audios / season1, season2 ... / class1, class 2 / archivos .mp3

  • libros / archivos .pdf

La aplicación de Android necesita obtener la lista de subcarpetas y archivos.

La solución es capturar el evento de carga en el almacenamiento y crear la misma estructura en firestore utilizando la función de nube.

Paso 1: Cree manualmente una colección de 'almacenamiento' y un documento de 'audios / libros' en firestore

ingrese la descripción de la imagen aquí

Paso 2: configurar la función de nube

Puede tardar unos 15 minutos: https://www.youtube.com/watch?v=DYfP-UIKxH0&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=1

Paso 3: captura el evento de carga usando la función de nube

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
const path = require('path');

export const onFileUpload = functions.storage.object().onFinalize(async (object) => {
        let filePath = object.name; // File path in the bucket.
        const contentType = object.contentType; // File content type.
        const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.
        if (metageneration !== "1") return;

        // Get the file name.
        const fileName = path.basename(filePath);
        filePath = filePath.substring(0, filePath.length - 1);
        console.log('contentType ' + contentType);
        console.log('fileName ' + fileName);
        console.log('filePath ' + filePath);
        console.log('path.dirname(filePath) ' + path.dirname(filePath));
        filePath = path.dirname(filePath);
        const pathArray = filePath.split("/");
        let ref = '';
        for (const item of pathArray) {
            if (ref.length === 0) {
                ref = item;
            }
            else {
                ref = ref.concat('/sub/').concat(item);
            }
        }

        ref = 'storage/'.concat(ref).concat('/sub')
        admin.firestore().collection(ref).doc(fileName).create({})
                .then(result => {console.log('onFileUpload:updated')})
                .catch(error => {
                    console.log(error);
                });
    });

Paso 4: recupere la lista de carpetas / archivos en la aplicación de Android usando firestore

private static final String STORAGE_DOC = "storage/";
    public static void getMediaCollection(String path, OnCompleteListener onCompleteListener) {
        String[] pathArray = path.split("/");
        String doc = null;
        for (String item : pathArray) {
            if (TextUtils.isEmpty(doc)) doc = STORAGE_DOC.concat(item);
            else doc = doc.concat("/sub/").concat(item);
        }
        doc = doc.concat("/sub");

        getFirestore().collection(doc).get().addOnCompleteListener(onCompleteListener);
    }

Paso 5: obtener la URL de descarga

public static void downloadMediaFile(String path, OnCompleteListener<Uri> onCompleteListener) {
        getStorage().getReference().child(path).getDownloadUrl().addOnCompleteListener(onCompleteListener);
    }

Nota

Tenemos que poner una colección "sub" a cada elemento ya que firestore no admite recuperar la lista de colecciones.

Me tomó 3 días encontrar la solución, con suerte te llevará 3 horas como máximo.

Salud.

thanhbinh84
fuente
Exactamente el mismo escenario en el que estoy trabajando. ¿Alguien puede enviarme un código de aleteo? porque solo pude subir lotes de archivos, no descargar.
Mahesh Peri
Flutter SDK (lenguaje de dardos)
Mahesh Peri
1
Cloud Firestore aún no admite flutter firebase.google.com/docs/firestore . El enfoque rápido es escribir API usando la función en la nube y luego acceder a estas API a través de restful como de costumbre. Puede llevar varias horas familiarizarse con la función de la nube; estos videos de capacitación son bastante fáciles de
asimilar
3

Ampliando la respuesta de Rosário Pereira Fernandes , para una solución de JavaScript:

  1. Instale firebase en su máquina
npm install -g firebase-tools

  1. En firebase init establecido JavaScriptcomo idioma predeterminado
  2. En la carpeta raíz del proyecto creado, ejecute npm installs
   npm install --save firebase
   npm install @google-cloud/storage
   npm install @google-cloud/firestore
   ... <any other dependency needed>
  1. Agregue dependencias no predeterminadas en su proyecto como
    "firebase": "^6.3.3",
    "@google-cloud/storage": "^3.0.3"

funciones / package.json

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "lint": "eslint .",
    "serve": "firebase serve --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "10"
  },
  "dependencies": {
    "@google-cloud/storage": "^3.0.3",
    "firebase": "^6.3.3",
    "firebase-admin": "^8.0.0",
    "firebase-functions": "^3.1.0"
  },
  "devDependencies": {
    "eslint": "^5.12.0",
    "eslint-plugin-promise": "^4.0.1",
    "firebase-functions-test": "^0.1.6"
  },
  "private": true
}

  1. Crea una especie de listAllfunción

index.js

var serviceAccount = require("./key.json");
const functions = require('firebase-functions');

const images = require('./images.js');

var admin = require("firebase-admin");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://<my_project>.firebaseio.com"
});

const bucket = admin.storage().bucket('<my_bucket>.appspot.com')

exports.getImages = functions.https.onRequest((request, response) => {
    images.getImages(bucket)
        .then(urls => response.status(200).send({ data: { urls } }))
        .catch(err => console.error(err));
})

images.js

module.exports = {
    getImages
}

const query = {
    directory: 'images'
};

function getImages(bucket) {
    return bucket.getFiles(query)
        .then(response => getUrls(response))
        .catch(err => console.error(err));
}

function getUrls(response) {
    const promises = []
    response.forEach( files => {
        files.forEach (file => {
            promises.push(getSignedUrl(file));
        });
    });
    return Promise.all(promises).then(result => getParsedUrls(result));
}

function getSignedUrl(file) {
    return file.getSignedUrl({
        action: 'read',
        expires: '09-01-2019'
    })
}

function getParsedUrls(result) {
    return JSON.stringify(result.map(mediaLink => createMedia(mediaLink)));
}

function createMedia(mediaLink) {
    const reference = {};
    reference.mediaLink = mediaLink[0];
    return reference;
}

  1. Ejecutar firebase deploypara cargar su función en la nube
  2. Llame a su función personalizada desde su aplicación

build.gradle

dependencies {
...
  implementation 'com.google.firebase:firebase-functions:18.1.0'
...
}

clase kotlin

  private val functions = FirebaseFunctions.getInstance()
  val cloudFunction = functions.getHttpsCallable("getImages")
  cloudFunction.call().addOnSuccessListener {...}

Con respecto al desarrollo posterior de esta función, encontré algunos problemas que podrían encontrarse aquí .

Víctor R. Oliveira
fuente
2

Para hacer esto con JS

Puede agregarlos directamente a su contenedor div, o puede enviarlos a una matriz. A continuación, se muestra cómo agregarlos a su div.

1) Cuando almacene sus imágenes en el almacenamiento, cree una referencia a la imagen en su base de datos de base de fuego con la siguiente estructura

/images/(imageName){
   description: "" , 
   imageSrc : (imageSource) 
}

2) Cuando cargue su documento, extraiga todas las URL de origen de la imagen de la base de datos en lugar del almacenamiento con el siguiente código

$(document).ready(function(){

var query = firebase.database().ref('images/').orderByKey();
query.once("value").then(function(snapshot){

    snapshot.forEach(function(childSnapshot){

        var imageName = childSnapshot.key;
        var childData = childSnapshot.val();
        var imageSource = childData.url;

        $('#imageGallery').append("<div><img src='"+imageSource+"'/></div>");

    })
})
});
MakDo
fuente
2

Puede utilizar el siguiente código. Aquí estoy cargando la imagen en el almacenamiento de Firebase y luego estoy almacenando la URL de descarga de la imagen en la base de datos de Firebase.

//getting the storage reference
            StorageReference sRef = storageReference.child(Constants.STORAGE_PATH_UPLOADS + System.currentTimeMillis() + "." + getFileExtension(filePath));

            //adding the file to reference 
            sRef.putFile(filePath)
                    .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            //dismissing the progress dialog
                            progressDialog.dismiss();

                            //displaying success toast 
                            Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show();

                            //creating the upload object to store uploaded image details 
                            Upload upload = new Upload(editTextName.getText().toString().trim(), taskSnapshot.getDownloadUrl().toString());

                            //adding an upload to firebase database 
                            String uploadId = mDatabase.push().getKey();
                            mDatabase.child(uploadId).setValue(upload);
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            progressDialog.dismiss();
                            Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    })
                    .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                            //displaying the upload progress 
                            double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
                            progressDialog.setMessage("Uploaded " + ((int) progress) + "%...");
                        }
                    });

Ahora, para obtener todas las imágenes almacenadas en la base de datos de firebase, puede usar

//adding an event listener to fetch values
        mDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                //dismissing the progress dialog 
                progressDialog.dismiss();

                //iterating through all the values in database
                for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                    Upload upload = postSnapshot.getValue(Upload.class);
                    uploads.add(upload);
                }
                //creating adapter
                adapter = new MyAdapter(getApplicationContext(), uploads);

                //adding adapter to recyclerview
                recyclerView.setAdapter(adapter);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                progressDialog.dismiss();
            }
        });

Para obtener más detalles, puede ver mi publicación Ejemplo de almacenamiento de Firebase .

Belal Khan
fuente
Seguí su ejemplo en el enlace, pero las imágenes no se muestran desde Firebase en RecyclerView
Wolfiebae
1

Entonces, tenía un proyecto que requería descargar activos del almacenamiento de base de fuego, así que tuve que resolver este problema yo mismo. Aquí es cómo :

1- Primero, haga un modelo de datos por ejemplo class Choice{}, en esa clase define una variable de cadena llamada Nombre de imagen para que sea así

class Choice {
    .....
    String imageName;
}

2- desde una base de datos / base de datos de fuego, vaya y codifique los nombres de las imágenes a los objetos, por lo que si tiene un nombre de imagen llamado Apple.png, cree el objeto que se

Choice myChoice = new Choice(...,....,"Apple.png");

3- Ahora, obtenga el enlace para los activos en su almacenamiento de base de fuego, que será algo así

gs://your-project-name.appspot.com/

como éste

4- finalmente, inicialice su referencia de almacenamiento de base de fuego y comience a obtener los archivos mediante un bucle como ese

storageRef = storage.getReferenceFromUrl(firebaseRefURL).child(imagePath);

File localFile = File.createTempFile("images", "png");
storageRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {

@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
    //Dismiss Progress Dialog\\
}

5- eso es todo

Brigth Ligth
fuente
1
#In Python

import firebase_admin
from firebase_admin import credentials
from firebase_admin import storage
import datetime
import urllib.request


def image_download(url, name_img) :
    urllib.request.urlretrieve(url, name_img)

cred = credentials.Certificate("credentials.json")

# Initialize the app with a service account, granting admin privileges
app = firebase_admin.initialize_app(cred, {
    'storageBucket': 'YOURSTORAGEBUCKETNAME.appspot.com',
})
url_img = "gs://YOURSTORAGEBUCKETNAME.appspot.com/"
bucket_1 = storage.bucket(app=app)
image_urls = []

for blob in bucket_1.list_blobs():
    name = str(blob.name)
    #print(name)
    blob_img = bucket_1.blob(name)
    X_url = blob_img.generate_signed_url(datetime.timedelta(seconds = 300), method='GET')
    #print(X_url)
    image_urls.append(X_url)


PATH = ['Where you want to save the image']
for path in PATH:
    i = 1
    for url  in image_urls:
        name_img = str(path + "image"+str(i)+".jpg")
        image_download(url, name_img)
        i+=1
Milán Hazra
fuente
No hay necesidad de API, solo necesita una clase Python simple y la palabra clave blob
Milan Hazra
0

Estoy usando AngularFirey utilizo lo siguiente para obtener todos losdownloadURL

getPhotos(id: string): Observable<string[]> {
    const ref = this.storage.ref(`photos/${id}`)
    return ref.listAll().pipe(switchMap(list => {
      const calls: Promise<string>[] = [];
      list.items.forEach(item => calls.push(item.getDownloadURL()))
      return Promise.all(calls)
    }));
}
Nabel
fuente
-1

Para Android, la mejor práctica es usar FirebaseUI y Glide.

Debe agregar eso en su gradle / aplicación para obtener la biblioteca. ¡Tenga en cuenta que ya tiene Glide!

implementation 'com.firebaseui:firebase-ui-storage:4.1.0'

Y luego en tu código usa

// Reference to an image file in Cloud Storage
StorageReference storageReference = FirebaseStorage.getInstance().getReference();

// ImageView in your Activity
ImageView imageView = findViewById(R.id.imageView);

// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
GlideApp.with(this /* context */)
        .load(storageReference)
        .into(imageView);
Dagnogo Jean-François
fuente