How do I upload multiple images automatically to Firebase Storage - Android Studio
I am developing an app, this app the user can already choose multiple images, but I am not able to upload the chosen images automatically to Firebase Storage. The user can log in. Can someone 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 answers
Hello, Luana!
This may not be the best method, but I think it will solve your problem.
First we must realize that to date, the SDK
of the 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 that we must pay attention to is to know when all uploads have been finalized. Explained this, we can proceed.
1 - create a class to package some information about the upload itself such as: Uri
and a boolean flag
indicating the state (up 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 we have to encapsulate the code responsible for the upload in a method so that we can work in a more modular way, since we will use a loop for the multiple uploads. Make the method receive as parameter the class we created in the 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 need to now 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 mount the wrappers
and call the upload method multiple times.
for (String s : listaFotosRecuperadas) {
upload(new Wrapper(Uri.parse(s)));
}
Oh, I was simmering, about the location of the images: do as follows
StorageReference firebaseRef = storageReference.child("galleries/" + mUserKey);
Thus Firebase Storage
will generate a directory schema in this way
galleries/{id_do_usuario}/imagem_1.jpg
.
.
.
galleries/{id_do_usuario}/imagem_n.jpg // n imagens
And if the directory does not 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 occur as expected. Anyway, that's the way. I hope this helps!