Android端Firebase循环上传图片时Push key不更新问题求解
问题原因
你遇到的问题是异步回调时序+全局变量共用共同导致的:
- for循环是同步执行的,会在极短时间内跑完所有迭代,每次循环都会给全局变量
imagePath赋新生成的push id - Firebase的
putBytes上传操作是异步任务,上传成功的回调会等到对应文件上传完成才触发,此时for循环早就已经执行完毕,全局的imagePath已经被覆盖为最后一次循环生成的id - 所有上传成功后调用
StoreLink时,读取到的都是最后这个全局的imagePath,所以都会往同一个id节点写入数据,导致覆盖。
修复方案
第一步:修改循环内的上传逻辑,把imagePath改为局部变量,回调时传入对应id
for (uploadCount = 0; uploadCount < ImageList.size(); uploadCount++) { // 改为局部变量,每次循环的id会被回调捕获,不会被后续循环覆盖 String currentImagePath = productRef.child(UID).child("images").push().getKey(); Uri IndividualImage = ImageList.get(uploadCount); StorageReference ImageName = productImagesRef.child(UID).child(currentImagePath); //Compress Images Bitmap bmp = null; try { bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), IndividualImage); } catch (IOException e) { e.printStackTrace(); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, 25, baos); byte[] data = baos.toByteArray(); //End of compressing //start on uploading compressed int finalUploadCount = uploadCount; ImageName.putBytes(data).addOnSuccessListener(taskSnapshot -> ImageName.getDownloadUrl() .addOnSuccessListener(uri -> { String url = String.valueOf(uri); // 把当前循环对应的id传入存储方法 StoreLink(url, currentImagePath, ImageList.size(), finalUploadCount); })); }
第二步:修改StoreLink方法,新增imagePath入参,调整finish触发逻辑
// 新增入参:当前图片对应的push id、总上传数量、当前上传下标 private void StoreLink(String url, String imagePath, int totalCount, int currentIndex) { HashMap<String ,Object> hashMap = new HashMap<>(); hashMap.put("image", url); hashMap.put("id", imagePath); productRef.child(UID).child("images").child(imagePath).updateChildren(hashMap).addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { // 只有最后一张上传完成再关闭弹窗和页面,避免提前退出 if (currentIndex == totalCount -1) { dialog.dismiss(); finish(); } } }); }
额外调整
删除你之前定义的全局imagePath变量,避免后续误调用。
内容的提问来源于stack exchange,提问作者user17547007
相关产品推荐
相关产品推荐

