Como obter uma lista de todos os arquivos no Cloud Storage em um aplicativo Firebase?

102

Estou trabalhando no upload de imagens, tudo funciona muito bem, mas tenho 100 fotos e gostaria de mostrar todas na minha View, como recebo a lista completa das imagens em uma pasta, não consigo encontrar nenhuma API para isso trabalhos.

Luis Ruiz Figueroa
fonte
Você pode postar uma solução completa de código?
ISS

Respostas:

92

Desde Firebase SDKs para JavaScript versão 6.1 , iOS versão 6.4 e Android versão 18.1, todos têm um método para listar arquivos.

A documentação é um pouco esparsa até agora, então recomendo conferir a resposta de Rosário para mais detalhes.


Resposta anterior, uma vez que esta abordagem ainda pode ser útil às vezes:

No momento, não há chamada de API no Firebase SDK para listar todos os arquivos em uma pasta do Cloud Storage de um aplicativo. Se precisar dessa funcionalidade, você deve armazenar os metadados dos arquivos (como os URLs de download) em um local onde possa listá-los. O Firebase Realtime Database e o Cloud Firestore são perfeitos para isso e permitem que você também compartilhe facilmente os URLs com outras pessoas.

Você pode encontrar uma boa amostra (mas um tanto envolvente) disso em nosso aplicativo de amostra FriendlyPix . O código relevante para a versão web está aqui , mas também existem versões para iOS e Android.

Frank van Puffelen
fonte
8
Você vai implementar isso no Firebase?
Píer de
55
Se eu precisar manter os URLs de todos os meus arquivos do Storage no Realtime Database, qual é a finalidade de ter uma hierarquia de pastas no Storage? todos os arquivos, com nome único, podem ser armazenados no mesmo nível, sem necessidade de pastas !!! você vê, isso é uma contradição !!! Basicamente, a principal razão por trás da hierarquia de pastas são as consultas curinga sem conhecimento prévio do que você tem em uma pasta, o que você não fornece de maneira razoável.
abedfar
7
O Firebase Storage é baseado no Google Cloud Storage, que faz exatamente o que você diz: ele armazena todos os objetos em uma longa lista. O Firebase Storage modela uma hierarquia em cima disso, reconhecidamente como uma abstração que vaza. Os motivos comuns para usar pastas no Firebase storage são para separação lógica de dados e para criar regras de segurança com base na estrutura de pastas.
Frank van Puffelen
8
O que acontece se a conexão do usuário for perdida após o upload e antes de salvar o downloadUrl no banco de dados? Como descobrimos os arquivos existentes em uma pasta nesse caso?
Oswaldo
10
E agora ? Existe alguma API direta para isso em 2018?
Diaz diaz
48

Desde maio de 2019, a versão 6.1.0 do Firebase SDK para Cloud Storage agora é compatível com a listagem de todos os objetos de um intervalo. Você só precisa ligar listAll()para um 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
      });
    }

Por favor , note que para utilizar esta função, você deve opt-in para a versão 2 de regras de segurança , que pode ser feito, fazendo rules_version = '2';a primeira linha de suas regras de segurança:

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

Eu recomendo verificar os documentos para referência futura.

Além disso, de acordo com a configuração , na Etapa 5, este script não é permitido, Node.jspois require("firebase/app");não retorna firebase.storage()como uma função. Isso só é conseguido usando import * as firebase from 'firebase/app';.

Rosário Pereira Fernandes
fonte
qual plugin você está usando
azheen
@azheen Presumo que você esteja usando Flutter. Infelizmente, isso ainda não está disponível em flutterfire. Pode acompanhar nesta edição
Rosário Pereira Fernandes
33

Desde março de 2017: com a adição do Firebase Cloud Functions e a integração mais profunda do Firebase com o Google Cloud, isso agora é possível.

Com o Cloud Functions, você pode usar o pacote Google Cloud Node para fazer operações épicas no Cloud Storage. Abaixo está um exemplo que obtém todos os URLs de arquivo em uma matriz do Cloud Storage. Esta função será acionada sempre que algo for salvo no armazenamento em nuvem do Google.

Nota 1 : esta é uma operação bastante dispendiosa do ponto de vista computacional, pois tem que percorrer todos os arquivos em um intervalo / pasta.

Nota 2 : Escrevi isso apenas como exemplo, sem dedicar muitos detalhes às promessas etc. Só para dar uma ideia.

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 isso lhe dê uma ideia geral. Para melhores exemplos de funções de nuvem, confira o repositório Github do Google cheio de exemplos de funções de nuvem para Firebase . Verifique também a documentação da API do Google Cloud Node

johnozbay
fonte
35
Isso é muito estúpido que o firebase não apenas adicione esta api ao firebase sdk
Thaina
4
@Thaina acho que tem a ver com escala. Eles precisam pensar não apenas em pequenos aplicativos, mas também em gigantes. E se um caminho tiver milhares de arquivos. Essa operação consumiria muito poder de computação e teria que se referir a um banco de dados para cada chamada aparentemente inocente e simples. Quanto mais me aprofundo no uso do firebase em escala, melhor entendo por que certos compromissos foram feitos.
johnozbay
1
Neste gcs api, também tem limite e paginação. É responsabilidade do consumidor da API saber o risco e tentar escolher o método que pode escalar. Mas ser superprotetor de modo a cortar nossa opção não é uma boa decisão. Eles podem cobrar por carga pesada se realmente custar
Thaina
1
esta deve ser a melhor resposta! Obrigado pelo aviso. Atualmente, a sintaxe difere do seu exemplo. Em vez de enviar um retorno de chamada como parâmetro, você tem que encadear um .thencomo este:this.bucket .getFiles({ prefix: 'path/to/directory' }) .then((arr) => {})
JP Lew
1
@JPLew De nada :) Com relação à sintaxe, eles retornam uma promessa somente se o retorno de chamada for excluído. Portanto, é seguro usar o que você preferir. Veja o exemplo aqui: cloud.google.com/nodejs/docs/reference/storage/1.3.x/…
johnozbay
20

Como não há idioma listado, responderei em Swift. É altamente recomendável usar o Firebase Storage e o Firebase Realtime Database juntos para realizar listas de downloads:

Compartilhado:

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

Envio:

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

Baixar:

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 obter mais informações, consulte Zero to App: Develop with Firebase , e seu código-fonte associado , para um exemplo prático de como fazer isso.

Mike McDonald
fonte
3
Mas como faço para obter o mesmo resultado com o Cloud Firestore?)
Max Kraev
5

Uma solução alternativa pode ser criar um arquivo (ou seja, list.txt) sem nada dentro, neste arquivo você pode definir os metadados personalizados (ou seja, um Mapa <String, String>) com a lista de todos os URLs do arquivo.
Portanto, se você precisar fazer o downlaod de todos os arquivos em um feed, primeiro faça o download dos metadados do arquivo list.txt e, em seguida, itere os dados personalizados e faça o download de todos os arquivos com os URLs no mapa.

Andrea
fonte
4
Sim, esta é uma solução alternativa, mas não pode lidar com gravações simultâneas em um único list.txt
linquize
5

Eu também encontrei esse problema quando estava trabalhando em meu projeto. Eu realmente gostaria que eles fornecessem um método API final. Enfim, foi assim que eu fiz: quando você estiver carregando uma imagem para o armazenamento do Firebase, crie um objeto e passe esse objeto para o banco de dados do Firebase ao mesmo tempo. Este objeto contém o URI de download da imagem.

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

Posteriormente, quando quiser baixar imagens de uma pasta, basta iterar os arquivos dessa pasta. Esta pasta tem o mesmo nome que a "pasta" no Firebase storage, mas você pode nomeá-la como quiser. Eu os coloquei em uma discussão separada.

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

        }
    });

Agora que tenho uma lista de objetos contendo os URIs para cada imagem, posso fazer o que quiser com eles. Para carregá-los em imageView, criei outro thread.

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

Isso retorna uma lista de Bitmap, quando termina eu simplesmente os anexei ao ImageView na atividade principal. Os métodos abaixo são @Override porque eu tenho interfaces criadas e escuto a conclusão em outros 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);
    }
}

Observe que eu tenho que esperar que a imagem da lista seja retornada primeiro e depois chamar o thread para trabalhar no bitmap da lista. Nesse caso, a imagem contém o 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);
}

Espero que alguém ache útil. Também servirá como uma linha de guilda para mim no futuro.

Tao
fonte
5

Mais uma maneira de adicionar a imagem ao banco de dados usando o Cloud Function para rastrear todas as imagens enviadas e armazená-las no banco de dados.

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 aqui: https://gist.github.com/bossly/fb03686f2cb1699c2717a0359880cf84

Oleg Baidalka
fonte
5

Para o node js, usei 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
fonte
Você acabou de salvar meu dia !!
hugo blanc
4

Você pode listar arquivos em um diretório de armazenamento do firebase pelo método listAll (). Para usar este método, é necessário implementar esta versão do Firebase Storage. 'com.google.firebase: firebase-storage: 18.1.1'

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

Lembre-se de atualizar as Regras de segurança para a versão 2.

Yonghwan Shin
fonte
3

Na verdade, isso é possível, mas apenas com uma API do Google Cloud em vez de uma do Firebase. É porque um Firebase Storage é um Google Cloud Storage Bucket que pode ser facilmente alcançado com as APIs do Google Cloud. No entanto, você precisa usar OAuth para autenticação em vez do Firebase.

Zen M
fonte
3

Eu enfrentei o mesmo problema, o meu é ainda mais complicado.

O administrador fará o upload dos arquivos de áudio e PDF para o armazenamento:

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

  • livros / arquivos .pdf

O aplicativo Android precisa obter a lista de subpastas e arquivos.

A solução é capturar o evento de upload no armazenamento e criar a mesma estrutura no firestore usando a função de nuvem.

Etapa 1: Crie manualmente a coleção de 'armazenamento' e o documento 'áudios / livros' no Firestore

insira a descrição da imagem aqui

Etapa 2: configurar a função de nuvem

Pode levar cerca de 15 minutos: https://www.youtube.com/watch?v=DYfP-UIKxH0&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=1

Etapa 3: capturar o evento de upload usando a função de nuvem

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

Etapa 4: recuperar a lista de pastas / arquivos no aplicativo Android usando o 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);
    }

Etapa 5: obter url de download

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

Nota

Temos que colocar "sub" coleção para cada item, pois o firestore não oferece suporte para recuperar a lista de coleção.

Levei 3 dias para descobrir a solução, espero que leve 3 horas no máximo.

Felicidades.

Thanhbinh84
fonte
Exatamente o mesmo cenário em que estou trabalhando. Alguém pode me enviar código de vibração? porque eu só consegui fazer upload de lotes de arquivos, não baixar.
Mahesh Peri
Flutter SDK (linguagem de dardo)
Mahesh Peri
1
O cloud firestore ainda não é compatível com flutter firebase.google.com/docs/firestore . A abordagem rápida é escrever API usando a função de nuvem e, em seguida, acessar essa API via restful como de costume. Pode levar várias horas para se familiarizar com a função da nuvem, esses vídeos de treinamento são muito fáceis de engolir: D youtube.com/…
thanhbinh84
3

Prolongando a resposta de Rosário Pereira Fernandes , para uma solução JavaScript:

  1. Instale o Firebase em sua máquina
npm install -g firebase-tools

  1. No firebase init definido JavaScriptcomo idioma padrão
  2. Na pasta raiz do projeto criado, execute instalações npm
   npm install --save firebase
   npm install @google-cloud/storage
   npm install @google-cloud/firestore
   ... <any other dependency needed>
  1. Adicione dependências não padrão em seu projeto, como
    "firebase": "^6.3.3",
    "@google-cloud/storage": "^3.0.3"

functions / 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. Crie uma espécie de listAllfunção

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. Execute firebase deploypara carregar sua função de nuvem
  2. Chame sua função personalizada de seu aplicativo

build.gradle

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

aula de kotlin

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

Em relação ao desenvolvimento deste recurso, encontrei alguns problemas que podem ser encontrados aqui .

Victor R. Oliveira
fonte
2

Para fazer isso com JS

Você pode anexá-los diretamente ao seu contêiner div ou pode enviá-los para uma matriz. A seguir, você verá como anexá-los ao seu div.

1) Ao armazenar suas imagens no armazenamento, crie uma referência à imagem em seu banco de dados Firebase com a seguinte estrutura

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

2) Quando você carrega o documento, extraia todos os URLs de origem da imagem do banco de dados, em vez do armazenamento com o seguinte 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
fonte
2

Você pode usar o seguinte código. Aqui, estou enviando a imagem para o armazenamento do firebase e, em seguida, estou armazenando o url de download da imagem no banco de dados do 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) + "%...");
                        }
                    });

Agora, para buscar todas as imagens armazenadas no banco de dados do firebase, você pode 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 mais detalhes, você pode ver meu exemplo de armazenamento de Firebase post .

Belal Khan
fonte
Segui seu exemplo no link, mas as imagens não estão sendo exibidas do Firebase no RecyclerView
Wolfiebae
1

Então, eu tinha um projeto que exigia o download de recursos do armazenamento do Firebase, então tive que resolver esse problema sozinho. Aqui está como :

1- Primeiro, faça um modelo de dados por exemplo class Choice{}, nessa classe define uma variável String chamada nome da imagem para que seja assim

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

2- a partir de um banco de dados / banco de dados firebase, codifique os nomes das imagens para os objetos, portanto, se você tiver um nome de imagem chamado Apple.png, crie o objeto a ser

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

3- Agora, obtenha o link para os ativos em seu armazenamento do Firebase, que será algo parecido com isso

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

como este

4 - por fim, inicialize sua referência de armazenamento firebase e comece a obter os arquivos por um loop como esse

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- é isso

Brigth Ligth
fonte
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
fonte
Não há necessidade de API, você só precisa de uma classe Python simples e da palavra
Milan Hazra
0

Estou usando AngularFiree uso o seguinte para obter todos osdownloadURL

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
fonte
-1

Para Android, a melhor prática é usar FirebaseUI e Glide.

Você precisa adicionar isso ao seu gradle / app para obter a biblioteca. Observe que ele já tem o Glide nele!

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

E então, em seu código, use

// 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
fonte