【问题标题】:Upload multiple images to firebase storage将多张图片上传到 Firebase 存储
【发布时间】:2018-02-26 13:53:04
【问题描述】:

我使用 firebase 构建了一个聊天应用程序,我想将多个图像发送到 firebase 存储。

使用这个库

编译'com.github.darsh2:MultipleImageSelect:3474549'

在顶部

private StorageReference storageRef;
private FirebaseApp app;
private FirebaseStorage storage;

onCreate()方法

app = FirebaseApp.getInstance();
storage =FirebaseStorage.getInstance(app);

按钮点击动作

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

活动结果

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

    }

【问题讨论】:

  • 有什么问题?
  • 我无法上传任何图片。发生了StorageException
  • 请使用堆栈跟踪编辑您的问题,您可以从 logcat 获得。
  • 大家注意,getDownloadUrlTaskSnapshot 对象下的用法不再有效。它现在属于最初用于上传文件的DocumentReference 实例。

标签: android firebase firebase-storage


【解决方案1】:

变量

  • 私有静态最终 int PICK_IMAGE = 1;
  • 按钮选择器Btn,上传器Btn;
  • TextView 警报;
  • 私有 Uri ImageUri;
  • ArrayList ImageList = new ArrayList();
  • private int upload_count = 0;
  • 私有 ProgressDialog progressDialog;
  • ArrayList urlStrings;

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


        }
    });

上传按钮

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

存储指向 Firebase 实时数据库的链接

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

        }
    }
}

}

【讨论】:

    【解决方案2】:

    一切正常。

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

    【讨论】:

    • 感谢您发布解决方案
    【解决方案3】:

    对于从图库中选择的具有相同顺序的图像的返回列表 imageUrls 不要为每个 uri 使用 for 循环

    在您获得ArrayList&lt;Uri&gt; imageUriList 并且您现在想将其上传到 Firebase 存储然后以您选择的相同顺序返回每个图像的 url 列表,所以我在下面的方法中使用 recursion 直到上传所有的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 
                    
                    });
    
    
        }
    

    所以现在从 OnActivityResult 中获取 imageUriList 值后,我们可以通过 this 调用方法;​​

    uploadImages(new ArrayList<>(),uriFilesList);
    

    当完成上传所有图片后,您可以在里面处理它

     private void allImageUploadedNow(ArrayList<String> imagesUrl){
    
      //handle imagesUrl
    }
    

    【讨论】:

      【解决方案4】:

      我创建了这个实用程序类,以在协程的帮助下使用 kotlin 将多个图像上传到 firebase 存储。如果您有任何改进,请告诉我。

      你需要先添加这些依赖。

      实现 'com.google.firebase:firebase-storage-ktx:19.1.1'

      //Firebase 通过 kotlinx-coroutines-play-services 库增加对 Coroutines 的支持

      实现“org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.1”

      更多信息请查看linkgithub 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()
      }
      

      }

      【讨论】:

        猜你喜欢
        • 2020-12-05
        • 1970-01-01
        • 2017-12-03
        • 2020-06-24
        • 2020-11-19
        • 2020-06-24
        • 1970-01-01
        相关资源
        最近更新 更多