Reputation: 258
i build a chat application using firebase and i want to send multiple image to firebase storage.
using this library
compile 'com.github.darsh2:MultipleImageSelect:3474549'
At the top
private StorageReference storageRef;
private FirebaseApp app;
private FirebaseStorage storage;
onCreate()Method
app = FirebaseApp.getInstance();
storage =FirebaseStorage.getInstance(app);
button click action
Gallary.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ChatActivity.this, AlbumSelectActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_LIMIT, 10);
startActivityForResult(intent, Constants.REQUEST_CODE);
pwindo1.dismiss();
}
});
Activity result
if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK) {
ArrayList<Image> images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
Uri uri = Uri.parse(String.valueOf(images));
storageRef = storage.getReference("photos");
final StorageReference photoRef = storageRef.child(uri.getLastPathSegment());
photoRef.putFile(uri)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
String content = downloadUrl.toString();
if (content.length() > 0) {
editWriteMessage.setText("");
Message newMessage = new Message();
newMessage.text = content;
newMessage.idSender = StaticConfig.UID;
newMessage.idReceiver = roomId;
newMessage.timestamp = System.currentTimeMillis();
FirebaseDatabase.getInstance().getReference().child("message/" + roomId).push().setValue(newMessage);
}
}
});
}
Upvotes: 5
Views: 27163
Reputation: 9
In my case of uploading multiple images into firebase I have used forEach(). forEach() method had helped me to upload images successfully into firebase
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
const Product =()=>{
const [file, setFile] =useState([])
Object.values(file).forEach(val => {
const storage = getStorage();
const storageRef = ref(storage, 'images/val.name');
const uploadTask = uploadBytesResumable(storageRef, val);
uploadTask.on('state_changed',
(snapshot) => {
number of bytes to be uploaded
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
switch (snapshot.state) {
case 'paused':
console.log('Upload is paused');
break;
case 'running':
console.log('Upload is running');
break;
}
},
(error) => {
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
console.log('File available at', downloadURL);
});
}
);
})
return (
<button onClick={(e) => setFile(e.target.files)}/>
)
}
Upvotes: 0
Reputation: 1352
This utility class I create it to upload multiple images to firebase storage using kotlin with help of coroutine. if you have any enhancement please tell me.
you need to add these dependencies firstly.
implementation 'com.google.firebase:firebase-storage-ktx:19.1.1'
//Firebase adds support to Coroutines through the kotlinx-coroutines-play-serviceslibrary
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.1"
for more info check link, github link
object FirebaseUtils {
suspend fun uploadPhotos(photosUri: ArrayList<File>): List<PhotoUrl> {
val storageRef = Firebase.storage.reference
val photosUrls = ArrayList<PhotoUrl>()
val uploadedPhotosUriLink = withContext(CoroutineScope(Dispatchers.IO).coroutineContext) {
(photosUri.indices).map { index ->
async(Dispatchers.IO) {
uploadPhoto(storageRef, photosUri[index])
}
}
}.awaitAll()
uploadedPhotosUriLink.forEach { photoUriLink -> photosUrls.add(PhotoUrl(photoUriLink.toString())) }
return photosUrls
}
private suspend fun uploadPhoto(storageRef: StorageReference, photoFile: File): Uri {
val fileName = UUID.randomUUID().toString()
val fileUri = Uri.fromFile(photoFile)
return storageRef.child(fileName)
.putFile(fileUri)
.await()
.storage
.downloadUrl
.await()
}
}
Upvotes: 3
Reputation: 3658
For return list imageUrls with same order of images selected from gallery don't use for loop for every uri
after you get ArrayList<Uri> imageUriList
and you want now upload it to firebase storage then return the list of url for every image in same order your selected it, so i use recursion on below method until upload all uri
private void uploadImages(@NonNull ArrayList<String> imagesUrl,ArrayList<Uri> imageUriList) {
StorageReference storageReference = FirebaseStorage.getInstance().getReference("Products").child(UUID.randomUUID().toString());
Uri uri = imageUriList.get(imagesUrl.size());
storageReference
.putFile(uri).addOnSuccessListener(taskSnapshot ->
storageReference.getDownloadUrl().addOnCompleteListener(task -> {
String url = Objects.requireNonNull(task.getResult()).toString();
imagesUrl.add(url);
//if same size so all image is uploaded, then sent list of url to to some method
if(imagesUrl .size() == imageUriList.size()){
allImageUploadedNow(imagesUrl);
}else {
uploadImages(imagesUrl);
}
}))
.addOnFailureListener(e -> {
Log.e("OnFailureImageListener", Objects.requireNonNull(e.getMessage()));
//some image is fails to upload
});
}
so now after get imageUriList
value from OnActivityResult we can call method by this;
uploadImages(new ArrayList<>(),uriFilesList);
and when finish to upload all image you can handle it inside
private void allImageUploadedNow(ArrayList<String> imagesUrl){
//handle imagesUrl
}
Upvotes: 2
Reputation: 71
Variables
onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uploaderBtn = findViewById(R.id.uploader);
chooserBtn = findViewById(R.id.chooser);
alert = findViewById(R.id.alert);
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Uploading Images please Wait.........!!!!!!");
chooserBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(intent, PICK_IMAGE);
}
});
Uploader Button
uploaderBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
urlStrings = new ArrayList<>();
progressDialog.show();
alert.setText("If Loading Takes to long press button again");
StorageReference ImageFolder = FirebaseStorage.getInstance().getReference().child("ImageFolder");
for (upload_count = 0; upload_count < ImageList.size(); upload_count++) {
Uri IndividualImage = ImageList.get(upload_count);
final StorageReference ImageName = ImageFolder.child("Images" + IndividualImage.getLastPathSegment());
ImageName.putFile(IndividualImage).addOnSuccessListener(
new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
ImageName.getDownloadUrl().addOnSuccessListener(
new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
urlStrings.add(String.valueOf(uri));
if (urlStrings.size() == ImageList.size()){
storeLink(urlStrings);
}
}
}
);
}
}
);
}
}
});
}
if (urlStrings.size() == ImageList.size()){
storeLink(urlStrings);
}
Store Links To Firebase Realtime Database
private void storeLink(ArrayList<String> urlStrings) {
HashMap<String, String> hashMap = new HashMap<>();
for (int i = 0; i <urlStrings.size() ; i++) {
hashMap.put("ImgLink"+i, urlStrings.get(i));
}
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("User");
databaseReference.push().setValue(hashMap)
.addOnCompleteListener(
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Successfully Uplosded", Toast.LENGTH_SHORT).show();
}
}
}
).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(MainActivity.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
progressDialog.dismiss();
alert.setText("Uploaded Successfully");
uploaderBtn.setVisibility(View.GONE);
ImageList.clear();
}
onActivityResult()
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE) {
if (resultCode == RESULT_OK) {
if (data.getClipData() != null) {
int countClipData = data.getClipData().getItemCount();
int currentImageSlect = 0;
while (currentImageSlect < countClipData) {
ImageUri = data.getClipData().getItemAt(currentImageSlect).getUri();
ImageList.add(ImageUri);
currentImageSlect = currentImageSlect + 1;
}
alert.setVisibility(View.VISIBLE);
alert.setText("You have selected" + ImageList.size() + "Images");
chooserBtn.setVisibility(View.GONE);
} else {
Toast.makeText(this, "Please Select Multiple Images", Toast.LENGTH_SHORT).show();
}
}
}
}
}
Upvotes: 7
Reputation: 258
It is working fine.
if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK) {
ArrayList<Image> images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
Uri[] uri=new Uri[images.size()];
for (int i =0 ; i < images.size(); i++) {
uri[i] = Uri.parse("file://"+images.get(i).path);
storageRef = storage.getReference("photos");
final StorageReference ref = storageRef.child(uri[i].getLastPathSegment());
ref.putFile(uri[i])
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
String content = downloadUrl.toString();
if (content.length() > 0) {
editWriteMessage.setText("");
Message newMessage = new Message();
newMessage.text = content;
newMessage.idSender = StaticConfig.UID;
newMessage.idReceiver = roomId;
newMessage.timestamp = System.currentTimeMillis();
FirebaseDatabase.getInstance().getReference().child("message/" + roomId).push().setValue(newMessage);
}
}
});
}
}
Upvotes: 6