Android端相机拍摄图片上传Firebase Storage出现StorageException异常如何解决
问题排查与修复方案
1. 依赖冲突修复
你的Gradle配置同时混用了AndroidX和旧版Support库,还重复声明了Firebase依赖、同时使用版本号指定和BOM版本管理,首先清理build.gradle依赖部分:
- 删除所有带独立版本号的Firebase依赖声明,统一由BOM管理
- 删除所有旧版
com.android.support相关依赖,替换为对应的AndroidX组件
清理后的dependencies参考:
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.annotation:annotation:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.1' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' // 只保留一次Firebase BOM声明 implementation platform('com.google.firebase:firebase-bom:28.4.1') implementation 'com.google.firebase:firebase-storage' implementation 'com.google.firebase:firebase-database' implementation 'com.google.firebase:firebase-auth' implementation 'com.google.firebase:firebase-analytics' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' }
2. 拍照逻辑修复
你当前的拍照代码没有把存储路径提前传给相机应用,导致你要上传的image_uri对应的文件根本不存在:
- 启动拍照Intent时就要传入
MediaStore.EXTRA_OUTPUT参数,不要在onActivityResult里才设置 - Android 7.0及以上版本不能直接使用
Uri.fromFile,需要配置FileProvider生成Uri
修复后的拍照代码:
private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); try { File dir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); File imgFile=new File(dir,GetPictureName()); // Android 7.0+ 用FileProvider生成Uri,需要提前在清单文件配置FileProvider if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { image_uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", imgFile); } else { image_uri=Uri.fromFile(imgFile); } // 启动拍照前就把输出路径传给intent takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } catch (ActivityNotFoundException e) { e.printStackTrace(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { // 不需要从data拿缩略图,直接读取image_uri对应的图片即可 imgUpload.setImageURI(image_uri); saveToFirebase(); } }
同时需要在清单文件中添加FileProvider配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
再在res/xml目录下新建file_paths.xml:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="pictures" path="Pictures/" /> </paths>
3. Storage引用路径修复
你当前的Storage根路径多了多余的/gs:后缀,修正如下:
// 删掉末尾多余的/gs: StorageReference storageRef = storage.getReferenceFromUrl("gs://smart-worker-c73c4.appspot.com");
4. 安全规则验证
测试阶段可以先将Firebase Storage的安全规则临时改为如下配置,验证是否是规则限制导致的上传失败:
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; // 如果还没做登录逻辑,临时改为allow read, write: if true; 验证完成后及时修改为安全规则 } } }
完成以上修改后重新运行测试即可解决上传异常问题。
内容的提问来源于stack exchange,提问作者Muzzammil Hussain
相关产品推荐
相关产品推荐

