How I Upload Multiple Images Automatically to Firebase Storage - Android Studio

Asked

Viewed 415 times

0

I am developing an app, this app the user can already choose multiple images, but I am not able to upload the images chosen automatically to Firebase Storage. The user can already authenticate. Someone can help me, how to do this upload process and create together folder that will store the images through each id already authenticated?

public class TelaverGaleriaActivity extends AppCompatActivity {
    private static final int SELECAO_GALERIA = 1;
    Button botaoGaleria;
    private StorageReference storageReference;
    private String identificadorUsuario;
    private List<String> listaFotosRecuperadas = new ArrayList<>();



    //solicitacao de permissao
    private String[] permissoesNecessarias = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE

    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_telaver_galeria);

        //configurações iniciais
        storageReference = ConfiguracaoFireBase.getReferenciaStorage();
        identificadorUsuario = UsuarioFirebase.getIdentificadorUsuario();

        //validar as permissoes
        Permissao.validarPermissoes(permissoesNecessarias, this, 1);

        botaoGaleria = findViewById(R.id.botaoParaGaleria);

        //criar evento onclick para que o usuario tenha acesso a galeria clicando no botao
        botaoGaleria.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent();
                intent.setType("image/*");
                intent.putExtra(EXTRA_ALLOW_MULTIPLE, true);
                intent.setAction(ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Selecione Imagem"), SELECAO_GALERIA);

            }
        });


    }

    //pegar as  varias foto que o usuario selecionou ok ok ok
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SELECAO_GALERIA) {
            if (resultCode == TelaverGaleriaActivity.RESULT_OK) {

                if (data.getClipData() != null) {
                    int count = data.getClipData().getItemCount();
                    Log.i("count", String.valueOf(count));
                    int currentItem = 0;
                    while (currentItem < count) {
                        Uri imagemUri = data.getClipData().getItemAt(currentItem).getUri();

                        Log.i("uri", imagemUri.toString());
                        listaFotosRecuperadas.add(String.valueOf(imagemUri));
                        currentItem = currentItem + 1;
                    }
                    Log.i("listsize", String.valueOf(listaFotosRecuperadas.size()));
                } else if (data.getData() != null) {
                    String imagePath = data.getData().getPath();



                } else if (listaFotosRecuperadas.size() != 5){
                    exibirMensagemErro("Selecione pelo menos cinco fotos");

                }
                Uri imagemUri = Uri.fromFile(new File("imagens.jpg"));

                StorageReference firebaseRef = storageReference.child( storageReference +imagemUri.getLastPathSegment());
                StorageTask<UploadTask.TaskSnapshot> uploadTask = firebaseRef.putFile(imagemUri);

                uploadTask.addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception exception) {
                        Toast.makeText(TelaverGaleriaActivity.this, "Erro ao enviar imagens", Toast.LENGTH_SHORT).show();
                        // Handle unsuccessful uploads
                    }
                }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
                        // ...
                        Toast.makeText(TelaverGaleriaActivity.this, "Upload com sucesso", Toast.LENGTH_SHORT).show();

                    }
                });
            }


        }

    }

    private void exibirMensagemErro(String mensagem) {
        Toast.makeText(this, mensagem, Toast.LENGTH_SHORT).show();
    }

   /* private void salvarImagensFirebase() {
        Uri file = Uri.fromFile(new File("path/to/images/rivers.jpg"));
        StorageReference riversRef = storageReference.child(identificadorUsuario+file.getLastPathSegment());
        StorageTask<UploadTask.TaskSnapshot> uploadTask = riversRef.putFile(file);

        uploadTask.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception exception) {
                // Handle unsuccessful uploads
            }
        }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
                // ...
            }
        });

    }*/

    //caso permissao foi negada
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        for(int permissaoResultado : grantResults){
            if(permissaoResultado == PackageManager.PERMISSION_DENIED){
                alertaValidacaoPermissao();

            }

        }

    }
     private void alertaValidacaoPermissao(){
         AlertDialog.Builder builder = new AlertDialog.Builder(this );
         builder.setTitle("Permissoes Negadas");
         builder.setMessage("Para utilizar o app é necessario aceitar as permissoes");
         builder.setPositiveButton("Confirmar", new DialogInterface.OnClickListener() {
             @Override
             public void onClick(DialogInterface dialog, int which) {
                 finish();

             }
         });
         AlertDialog dialog = builder.create();
         dialog.show();
     }



    }


1 answer

2

Hello, Luana!

This may not be the best method, but I think it will solve your problem.

First we must realize that so far, the SDK of Firebase Storage does not support uploading multiple files at once. The solution would be to call multiple times the code responsible for a single upload. The second point we should be aware of is to know when all uploads have been completed. Explained this, we can proceed.

1 - Create a class to package some information about the upload itself like: Uri and a flag boolean indicating the state (upate or not).

Uploadwrapper.java

public class UploadWrapper {
    private Uri uri;
    private boolean uploaded;

    public UploadWrapper(Uri uri) {
        this.uri = uri;
    }

    /* Getters e setters desnecessários omitidos */

    public Uri getUri() {
        return uri;
    }

    public void setUploaded(boolean uploaded) {
        this.uploaded = uploaded;
    }

    public boolean isUploaded() {
        return uploaded;
    }
}

2 - Now let’s encapsulate the code responsible for the upload in a method so that we can work more modular, since we will use a loop for multiple uploads. Make the method receive as parameter the class we created in step 1.

    public void upload(UploadWrapper wrapper) {
      StorageTask<UploadTask.TaskSnapshot> uploadTask 
= firebaseRef.putFile(wrapper.getUri()); // Isso retorna a Uri da imagem

          uploadTask.addOnFailureListener(new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception exception) {
                   // Setar false aqui é irrelevante, pois o valor padrão já é false,
                   // mas server como ilustração de que o upload dessa imagem falhou
                   wrapper.setUploaded(false); 

                   // Agora adicione o wrapper à lista e cheque se o tamanho dela
                   // é igual ao tamanho da lista de uris: se sim, sabemos que
                   //  não há mais nada para upar e já podemos avisar ao 
                   // usuário
                   if (!mFinished.contains(wrapper)) mFinished.add(wrapper);
                   checkUploadFinished();   // Esse método vai checar se tudo já acabou
              })
              .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
              @Override
              public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                   // Repetindo tudo só que dessa vez setando a flag (uploaded)
                   // como true!
                   wrapper.setUploaded(true); 

                   // Verifica se já não foi adicionado à lista
                   if (!mFinished.contains(wrapper)) mFinished.add(wrapper);
                   checkUploadFinished();   // Esse método vai checar se tudo já acabou       
              }
           });
    }

3 - We now need to create a method that checks which images have been uploaded or not.

public void checkUploadFinished() {
   if (listaFotosRecuperadas.size() == mFinished.size()) {
        // Pronto! Todos os uploads foram concluídos e você
        // pode verificar quem teve sucesso ou falha na lista mFinished
        for(UploadWrapper wrapper : mFinished) {         
           if (wrapper.isUploaded) {               // Mas isso é opcional, você pode só mostrar um Toast
               // Foi upado com sucesso!
           }
        }

       // E não esqueça de esvaziar as listas depois que tudo acabar
       listaFotosRecuperadas.clear();
       mFinished.clear();  
    }
}

4 - Finally, create a loop to assemble the wrappers and call the upload method several times.

for (String s : listaFotosRecuperadas) {
    upload(new Wrapper(Uri.parse(s)));
}

Ah, I almost forgot, about the location of the images: do it like this

StorageReference firebaseRef = storageReference.child("galleries/" + mUserKey);

So the Firebase Storage will generate a directory schema this way

   galleries/{id_do_usuario}/imagem_1.jpg
    .
    .
    .
    galleries/{id_do_usuario}/imagem_n.jpg   // n imagens

And if the directory doesn’t exist, it will be created automatically. Don’t worry about it.

Warning that I have not tested this code so I do not know if in practice everything will take place as expected. Anyway, this is the way. I hope this helps!

  • Good evening Ivan all right? I tested the code you gave me adapting to the project, but I did not succeed. So I analyzed the contents again and I didn’t need to change much. In Activity result I redid the counter by calling the list of chosen images, I created a method just to get the files and stopped, and within Activity result I used Storagereference with Child to call idusuario (which I had already created a class)and create a folder for each id. Now every user when choosing the photos each has a specific folder, Ivan even so I thank, gratitude.

  • I’m glad I helped in some way. Abs!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.