Comment obtenir une liste de tous les fichiers de Cloud Storage dans une application Firebase?

102

Je travaille sur le téléchargement d'images, tout fonctionne très bien, mais j'ai 100 photos et je voudrais toutes les montrer dans mon View, comme je reçois la liste complète des images dans un dossier, je ne trouve aucune API pour cela travail.

Luis Ruiz Figueroa
la source
Pouvez-vous publier une solution de code complète?
ISS

Réponses:

92

Depuis les SDK Firebase pour JavaScript version 6.1 , iOS version 6.4 et Android version 18.1 ont tous une méthode pour répertorier les fichiers.

La documentation est un peu clairsemée jusqu'à présent, je vous recommande donc de consulter la réponse de Rosário pour plus de détails.


Réponse précédente, puisque cette approche peut encore être utile à certains moments:

Il n'y a actuellement aucun appel d'API dans le SDK Firebase pour répertorier tous les fichiers d'un dossier Cloud Storage à partir d'une application. Si vous avez besoin d'une telle fonctionnalité, vous devez stocker les métadonnées des fichiers (telles que les URL de téléchargement) dans un endroit où vous pouvez les répertorier. La base de données Firebase Realtime et Cloud Firestore sont parfaits pour cela et vous permettent également de partager facilement les URL avec d'autres.

Vous pouvez trouver un bon exemple (mais quelque peu compliqué) de ceci dans notre exemple d'application FriendlyPix . Le code pertinent pour la version Web est ici , mais il existe également des versions pour iOS et Android.

Frank van Puffelen
la source
8
Allez-vous l'implémenter sur Firebase?
Pier
55
Si j'ai besoin de conserver les URL de tous mes fichiers de stockage dans la base de données en temps réel, quel est le but d'avoir une hiérarchie de dossiers dans le stockage? tous les fichiers, ayant un nom unique, peuvent être stockés au même niveau, pas besoin de dossiers du tout !!! vous voyez, c'est une contradiction !!! Fondamentalement, la principale raison derrière la hiérarchie des dossiers est les requêtes génériques sans connaissance préalable de ce que vous avez dans un dossier, ce que vous ne fournissez pas raisonnablement.
abedfar le
7
Firebase Storage est basé sur Google Cloud Storage, qui fait exactement ce que vous dites: il stocke tous les objets dans une longue liste. Firebase Storage modélise une hiérarchie en plus de cela, certes comme une abstraction qui fuit. Les raisons courantes d'utilisation du dossier dans Firebase Storage sont la séparation logique des données et l'élaboration de règles de sécurité basées sur la structure des dossiers.
Frank van Puffelen
8
Que se passe-t-il si la connexion utilisateur est perdue après le téléchargement et avant d'enregistrer downloadUrl dans la base de données? Comment découvrons-nous les fichiers existants dans un dossier dans ce cas?
Oswaldo
10
Et maintenant ? Existe-t-il une API directe pour cela en 2018?
Diaz diaz
48

Depuis mai 2019, la version 6.1.0 du SDK Firebase pour Cloud Storage prend désormais en charge la liste de tous les objets d'un bucket. Il vous suffit d'appeler listAll()un 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
      });
    }

Veuillez noter que pour utiliser cette fonction, vous devez activer la version 2 des règles de sécurité , ce qui peut être fait en créant rules_version = '2';la première ligne de vos règles de sécurité:

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

Je recommanderais de vérifier les documents pour plus de références.

De plus, selon la configuration , à l'étape 5, ce script n'est pas autorisé Node.jscar require("firebase/app");il ne reviendra pas en firebase.storage()tant que fonction. Ceci n'est réalisé qu'en utilisant import * as firebase from 'firebase/app';.

Rosário Pereira Fernandes
la source
quel plugin utilisez-vous
azheen
@azheen Je suppose que vous utilisez Flutter. Malheureusement, ce n'est pas encore disponible sur flutterfire. Vous pouvez le suivre sur ce numéro
Rosário Pereira Fernandes
33

Depuis mars 2017: avec l'ajout de Firebase Cloud Functions et l'intégration plus poussée de Firebase avec Google Cloud, c'est désormais possible.

Avec Cloud Functions, vous pouvez utiliser le package Google Cloud Node pour effectuer des opérations épiques sur Cloud Storage. Vous trouverez ci-dessous un exemple qui récupère toutes les URL de fichiers dans un tableau à partir de Cloud Storage. Cette fonction sera déclenchée chaque fois qu'un élément est enregistré dans le stockage cloud Google.

Remarque 1 : Il s'agit d'une opération assez coûteuse en calcul, car elle doit parcourir tous les fichiers dans un compartiment / dossier.

Note 2 : J'ai écrit ceci juste à titre d'exemple, sans donner beaucoup de détails sur les promesses, etc. Juste pour donner une idée.

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);
      });
    });

  });

});

J'espère que cela vous donnera une idée générale. Pour de meilleurs exemples de fonctions cloud, consultez le référentiel Github de Google plein d'exemples Cloud Functions pour Firebase . Consultez également leur documentation sur l'API Google Cloud Node

johnozbay
la source
35
C'est trop stupide que Firebase n'ajoute pas simplement cette API dans Firebase SDK
Thaina
4
@Thaina Je pense que cela a à voir avec l'échelle. Ils doivent penser non seulement aux petites applications, mais aussi aux géants. Et si un chemin contient des milliers de fichiers. Cette opération consommerait beaucoup de puissance de calcul et il faudrait se référer à une base de données pour chaque appel apparemment innocent et simple. Plus je me suis mis à utiliser Firebase à grande échelle, mieux je comprends pourquoi certains compromis ont été faits.
johnozbay
1
Dans cette API gcs, il a également une limite et une pagination.Il incombe alors au consommateur de l'API de connaître le risque et d'essayer de choisir une méthode qui pourrait évoluer. Mais être surprotecteur afin de couper notre option n'est pas une bonne décision. Ils peuvent facturer une charge lourde si cela coûte vraiment
Thaina
1
cela devrait être la meilleure réponse! Merci pour l'information. Actuellement, la syntaxe diffère de votre exemple. Au lieu d'envoyer un callback comme paramètre, vous devez enchaîner un .thencomme ceci:this.bucket .getFiles({ prefix: 'path/to/directory' }) .then((arr) => {})
JP Lew
1
@JPLew Vous êtes les bienvenus :) En ce qui concerne la syntaxe, ils ne renvoient une promesse que si le rappel est exclu. Il est donc sûr d'utiliser celui que vous préférez. Voir l'exemple ici: cloud.google.com/nodejs/docs/reference/storage/1.3.x/…
johnozbay
20

Puisqu'il n'y a pas de langue répertoriée, je répondrai à cela en Swift. Nous vous recommandons vivement d'utiliser conjointement Firebase Storage et Firebase Realtime Database pour réaliser des listes de téléchargements:

Partagé:

// 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]()

Télécharger:

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)
}

Télécharger:

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)
  })
})

Pour plus d'informations, consultez Zero to App: Develop with Firebase , et son code source associé , pour un exemple pratique de la façon de procéder.

Mike McDonald
la source
3
Mais comment obtenir le même résultat avec Cloud Firestore?)
Max Kraev
5

Une solution de contournement peut être de créer un fichier (c'est-à-dire list.txt) sans rien à l'intérieur, dans ce fichier, vous pouvez définir les métadonnées personnalisées (c'est-à-dire une Map <String, String>) avec la liste de toutes les URL du fichier.
Donc, si vous avez besoin de télécharger tous les fichiers d'un fodler, vous téléchargez d'abord les métadonnées du fichier list.txt, puis vous parcourez les données personnalisées et téléchargez tous les fichiers avec les URL de la carte.

Andrea
la source
4
Oui, il s'agit d'une solution de contournement, mais ne peut pas gérer les écritures simultanées dans un seul list.txt
linquize
5

J'ai également rencontré ce problème lorsque je travaillais sur mon projet. Je souhaite vraiment qu'ils fournissent une méthode api de fin. Quoi qu'il en soit, voici comment je l'ai fait: lorsque vous téléchargez une image sur le stockage Firebase, créez un objet et transmettez cet objet à la base de données Firebase en même temps. Cet objet contient l'URI de téléchargement de l'image.

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);
        }
    });

Plus tard, lorsque vous souhaitez télécharger des images à partir d'un dossier, vous parcourez simplement les fichiers de ce dossier. Ce dossier porte le même nom que le "dossier" dans le stockage Firebase, mais vous pouvez les nommer comme vous le souhaitez. Je les mets dans un fil séparé.

 @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) {

        }
    });

Maintenant, j'ai une liste d'objets contenant les URI de chaque image, je peux faire ce que je veux en faire. Pour les charger dans imageView, j'ai créé un autre fil.

    @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;
}

Cela renvoie une liste de Bitmap, quand il est terminé, je les attache simplement à ImageView dans l'activité principale. Les méthodes ci-dessous sont @Override car j'ai des interfaces créées et j'écoute la fin dans d'autres threads.

    @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);
    }
}

Notez que je dois attendre que l'image de la liste soit renvoyée en premier, puis appeler le thread pour travailler sur la Bitmap de la liste. Dans ce cas, Image contient l'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);
}

Espérons que quelqu'un le trouve utile. Cela me servira également de ligne de guilde à l'avenir.

Tao
la source
5

Une autre façon d'ajouter l'image à la base de données à l'aide de la fonction Cloud pour suivre chaque image téléchargée et la stocker dans la base de données.

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
        });
    });
});

Code complet ici: https://gist.github.com/bossly/fb03686f2cb1699c2717a0359880cf84

Oleg Baidalka
la source
5

Pour le nœud js, j'ai utilisé ce code

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
la source
Vous venez de sauver ma journée !!
hugo blanc
4

Vous pouvez lister les fichiers dans un répertoire de stockage Firebase par la méthode listAll (). Pour utiliser cette méthode, vous devez implémenter cette version du stockage Firebase. "com.google.firebase: firebase-storage: 18.1.1"

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

Gardez à l'esprit que mettez à niveau les règles de sécurité vers la version 2.

Yonghwan Shin
la source
3

En fait, cela est possible, mais uniquement avec une API Google Cloud au lieu d'une de Firebase. C'est parce qu'un stockage Firebase est un bucket Google Cloud Storage qui peut être facilement atteint avec les API Google Cloud, mais vous devez utiliser OAuth pour l'authentification au lieu de celui de Firebase.

Zen M
la source
3

J'ai fait face au même problème, le mien est encore plus compliqué.

L'administrateur téléchargera les fichiers audio et pdf dans le stockage:

  • audios / saison1, saison2 ... / classe1, fichiers classe 2 / .mp3

  • livres / fichiers .pdf

L'application Android doit obtenir la liste des sous-dossiers et fichiers.

La solution capture l'événement de téléchargement sur le stockage et crée la même structure sur Firestore à l'aide de la fonction cloud.

Étape 1: Créez manuellement une collection 'stockage' et un document 'audios / livres' sur Firestore

entrez la description de l'image ici

Étape 2: configuration de la fonction cloud

Cela peut prendre environ 15 minutes: https://www.youtube.com/watch?v=DYfP-UIKxH0&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=1

Étape 3: Capturez l'événement de téléchargement à l'aide de la fonction cloud

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);
                });
    });

Étape 4: Récupérez la liste des dossiers / fichiers sur l'application Android à l'aide de 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);
    }

Étape 5: Obtenez l'URL de téléchargement

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

Remarque

Nous devons mettre une "sous" collection à chaque élément puisque Firestore ne prend pas en charge la récupération de la liste de la collection.

Il m'a fallu 3 jours pour trouver la solution, j'espère que cela vous prendra 3 heures au maximum.

À votre santé.

thanhbinh84
la source
Exactement le même scénario sur lequel je travaille. Quelqu'un peut-il m'envoyer du code flottant? parce que je n'ai qu'à télécharger un lot de fichiers, pas à télécharger.
Mahesh Peri
Flutter SDK (langue de fléchettes)
Mahesh Peri
1
cloud firestore ne prend pas encore en charge le flutter firebase.google.com/docs/firestore . L'approche rapide consiste à écrire une API à l'aide de la fonction cloud, puis à accéder à ces API via repos, comme d'habitude. Cela peut prendre plusieurs heures pour se familiariser avec la fonction cloud, ces vidéos de formation sont assez faciles à avaler: D youtube.com
...
3

Extension de la réponse de Rosário Pereira Fernandes , pour une solution JavaScript:

  1. Installez Firebase sur votre machine
npm install -g firebase-tools

  1. Sur firebase init défini JavaScriptcomme langue par défaut
  2. Sur le dossier racine du projet créé, exécutez les installations npm
   npm install --save firebase
   npm install @google-cloud/storage
   npm install @google-cloud/firestore
   ... <any other dependency needed>
  1. Ajoutez des dépendances non par défaut à votre projet comme
    "firebase": "^6.3.3",
    "@google-cloud/storage": "^3.0.3"

fonctions / 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. Créer une sorte de listAllfonction

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. Exécuter firebase deploy pour télécharger votre fonction cloud
  2. Appelez votre fonction personnalisée depuis votre application

build.gradle

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

classe kotlin

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

En ce qui concerne le développement ultérieur de cette fonctionnalité, je suis tombé sur quelques problèmes qui pourraient se trouver ici .

Victor R. Oliveira
la source
2

Pour faire cela avec JS

Vous pouvez les ajouter directement à votre conteneur div ou les pousser dans un tableau. Le tableau ci-dessous vous montre comment les ajouter à votre div.

1) Lorsque vous stockez vos images dans le stockage, créez une référence à l'image dans votre base de données Firebase avec la structure suivante

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

2) Lorsque vous chargez votre document, tirez toutes les URL de source d'image de la base de données plutôt que du stockage avec le code suivant

$(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
la source
2

Vous pouvez utiliser le code suivant. Ici, je télécharge l'image sur le stockage Firebase, puis je stocke l'URL de téléchargement d'image dans la base de données 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) + "%...");
                        }
                    });

Maintenant, pour récupérer toutes les images stockées dans la base de données Firebase, vous pouvez utiliser

//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();
            }
        });

Pour plus de détails, vous pouvez voir mon exemple de post Firebase Storage .

Belal Khan
la source
J'ai suivi votre exemple dans le lien, mais les images ne sont pas affichées depuis Firebase dans RecyclerView
Wolfiebae
1

J'avais donc un projet qui nécessitait le téléchargement d'actifs depuis le stockage Firebase, j'ai donc dû résoudre ce problème moi-même. Voici comment :

1- Tout d'abord, créez un modèle de données par exemple class Choice{}, dans cette classe définit une variable String appelée image Name, donc ce sera comme ça

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

2- à partir d'une base de données / base de données Firebase, allez et codez en dur les noms d'image sur les objets, donc si vous avez un nom d'image appelé Apple.png, créez l'objet à être

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

3- Maintenant, récupérez le lien pour les actifs dans votre stockage Firebase qui sera quelque chose comme ça

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

comme celui-ci

4- enfin, initialisez votre référence de stockage Firebase et commencez à récupérer les fichiers par une boucle comme ça

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- c'est tout

Brigth Ligth
la source
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
Milan Hazra
la source
Il n'y a pas besoin d'API, vous avez juste besoin d'une simple classe Python et du mot
Milan Hazra
0

J'utilise AngularFireet j'utilise ce qui suit pour obtenir tous lesdownloadURL

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
la source
-1

Pour Android, la meilleure pratique consiste à utiliser FirebaseUI et Glide.

Vous devez ajouter cela sur votre gradle / application afin d'obtenir la bibliothèque. Notez qu'il a déjà Glide dessus!

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

Et puis dans votre code utilisez

// 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
la source