You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase图片上传异常:存在的图片提示不存在及多图更新失败

问题分析与解决方案

问题1:错误提示「image file does not exist at uri」但图片实际存在

你的fileExists方法存在逻辑缺陷:当Uri是content://协议(比如从系统相册、媒体库选择的图片)时,uri.getPath()返回的并非真实本地文件路径,而是媒体数据库的内部标识,直接用File(uri.getPath())判断存在性必然返回false,导致错误提示。

修复方案

替换fileExists方法,通过ContentResolver检查Uri对应的资源是否可访问:

private boolean fileExists(Uri uri) {
    if (uri == null) return false;
    try {
        // 尝试打开输入流,能打开则说明资源存在且可访问
        InputStream inputStream = getContentResolver().openInputStream(uri);
        if (inputStream != null) {
            inputStream.close();
            return true;
        }
    } catch (IOException e) {
        Log.e(TAG, "Failed to check file existence: " + e.getMessage());
    }
    return false;
}

问题2:上传第二张及更多图片时无法更新到Firebase

当前代码的上传逻辑存在两个核心问题:

  1. save方法触发条件过于严格:只有当所有图片上传成功(uploadCount.incrementAndGet() == imageUris.size())时才会调用save,但只要有一张上传失败,这个条件就无法满足,导致所有成功上传的图片URL都无法更新到数据库。
  2. CountDownLatch与uploadCount的逻辑冲突:每个上传任务不管成功失败都会调用latch.countDown(),但save仅在全部成功时执行,导致latch等待完成后,可能没有触发数据库更新。

修复方案

调整上传逻辑,收集所有成功上传的图片URL,在所有上传任务完成后统一调用save方法更新数据库:

if (!imageUris.isEmpty()) {
    List<String> imageUrls = new ArrayList<>();
    CountDownLatch latch = new CountDownLatch(imageUris.size());

    for (int i = 0; i < imageUris.size(); i++) {
        Uri imageUri = imageUris.get(i);
        if (imageUri == null) {
            Log.e(TAG, "ImageUri is null.");
            latch.countDown();
            continue;
        }

        if (!fileExists(imageUri)) {
            Log.e(TAG, "Image file does not exist at Uri: " + imageUri.toString());
            latch.countDown();
            continue;
        }

        StorageReference imageRef = storageReference.child("hotel_images/" + hotelId + "/image" + (i + 1));
        UploadTask uploadTask = imageRef.putFile(imageUri);

        uploadTask.addOnSuccessListener(taskSnapshot -> {
            imageRef.getDownloadUrl().addOnSuccessListener(downloadUri -> {
                imageUrls.add(downloadUri.toString());
                latch.countDown();
            }).addOnFailureListener(e -> {
                Log.e("image upload", "Failed to get download URL: " + e.getMessage());
                latch.countDown();
            });
        }).addOnFailureListener(e -> {
            Log.e("image upload", "Upload failed: " + e.getMessage());
            latch.countDown();
        });
    }

    new Thread(() -> {
        try {
            latch.await();
            // 所有上传任务完成后,统一更新数据库
            save(hotelId, imageUrls, hotelName, hotelAddress, hotelDescription, hotelContact,
                 hotelEmail, roomTypes, cancellationPolicy, amenitiesHotel, gcashNumber, gcashName, reservationFee, latitude, longitude);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
} else {
    // 无图片时直接更新数据库
    save(hotelId, null, hotelName, hotelAddress, hotelDescription, hotelContact,
         hotelEmail, roomTypes, cancellationPolicy, amenitiesHotel, gcashNumber, gcashName, reservationFee, latitude, longitude);
}

额外注意点

  • 原代码中update方法的参数hotelId被onDataChange里的childSnapshot.getKey()覆盖,如果你的业务逻辑是要更新指定的hotelId,需要调整Query逻辑,避免遍历所有用户的酒店(当前Query是orderByChild("user_id").equalTo(userId),会返回该用户下的所有酒店)。
  • 建议在save方法中处理imageUrls为空的情况(比如所有图片上传失败时,是否保留原图片URL或清空)。

内容的提问来源于stack exchange,提问作者Kitlolz012

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:57:39