安卓Firebase Storage/Realtime Database权限异常:用户无对象访问权限
问题:Firebase存储上传时权限异常解决
我开发了一个包含按钮和ImageView的简易安卓应用,点击按钮可显示drawable中的图片。已编写将图片上传至Firebase的代码,但onAddFailureListener抛出异常:User does not have permission to access this object。尝试过相关Stack Overflow解决方案但无效,请问该如何解决?
相关代码
MainActivity 代码
public class MainActivity extends AppCompatActivity { private static final int PICK_IMAGE_REQUEST = 1; private Button mButtonChooseImage; private Button mButtonUpload; private TextView mTextViewShowUploads; private EditText mEditTextFileName; private ImageView mImageView; private ProgressBar mProgressBar; private Uri mImageUri; private StorageReference mStorageRef; private DatabaseReference mDatabaseRef; private StorageTask mUploadTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButtonChooseImage = findViewById(R.id.button_choose_image); mButtonUpload = findViewById(R.id.button_upload); mTextViewShowUploads = findViewById(R.id.text_view_show_uploads); mEditTextFileName = findViewById(R.id.edit_text_file_name); mImageView = findViewById(R.id.image_view); mProgressBar = findViewById(R.id.progress_bar); mStorageRef = FirebaseStorage.getInstance().getReference("uploads"); mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads"); mButtonChooseImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openFileChooser(); } }); mButtonUpload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mUploadTask != null && mUploadTask.isInProgress()) { Toast.makeText(MainActivity.this, "Upload in progress", Toast.LENGTH_SHORT).show(); } else { uploadFile(); } } }); mTextViewShowUploads.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openImagesActivity(); } }); } private void openFileChooser() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, PICK_IMAGE_REQUEST); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) { mImageUri = data.getData(); Picasso.get().load(mImageUri).into(mImageView); } } private String getFileExtension(Uri uri) { ContentResolver cR = getContentResolver(); MimeTypeMap mime = MimeTypeMap.getSingleton(); return mime.getExtensionFromMimeType(cR.getType(uri)); } private void uploadFile() { if (mImageUri != null) { StorageReference fileReference = mStorageRef.child(System.currentTimeMillis() + "." + getFileExtension(mImageUri)); mUploadTask = fileReference.putFile(mImageUri) .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { mProgressBar.setProgress(0); } }, 500); Toast.makeText(MainActivity.this, "Upload successful", Toast.LENGTH_LONG).show(); Upload upload = new Upload(mEditTextFileName.getText().toString().trim(), /* taskSnapshot.getMetadata().getReference().getDownloadUrl().toString()); String uploadId = mDatabaseRef.push().getKey(); mDatabaseRef.child(uploadId).setValue(upload); */ Objects.requireNonNull(taskSnapshot.getMetadata()).getReference().getDownloadUrl().toString()); String uploadId = mDatabaseRef.push().getKey(); assert uploadId != null; mDatabaseRef.child(uploadId).setValue(upload); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); } }) .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount()); mProgressBar.setProgress((int) progress); } }); } else { Toast.makeText(this, "No file selected", Toast.LENGTH_SHORT).show(); } } private void openImagesActivity() { Intent intent = new Intent(this, ImagesActivity.class); startActivity(intent); } }
Realtime Database 规则
{ "rules": { ".read": true, ".write": true } }
Storage 规则
rules_version = '2'; service firebase.storage { match /b/savephoto-a1cc3.appspot.com/o { match /{allPaths=**} { // Allow access by all users allow read, write; } } }
解决步骤
- 确认Storage规则生效:当前规则已设置为允许全量读写,需确保规则在Firebase控制台保存后已生效,规则修改后可能需要数分钟同步到服务器。
- 核对存储桶名称:检查规则中的存储桶
savephoto-a1cc3.appspot.com是否与Firebase控制台Storage页面显示的当前项目存储桶完全一致。 - 验证配置文件:确保安卓项目中的
google-services.json是从当前Firebase项目下载的最新版本,无配置错误。 - 修复下载URL异步获取问题:代码中直接调用
getDownloadUrl().toString()无法获取真实URL(该方法为异步操作),需改为异步回调方式获取,示例代码如下:taskSnapshot.getMetadata().getReference().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { String downloadUrl = uri.toString(); Upload upload = new Upload(mEditTextFileName.getText().toString().trim(), downloadUrl); String uploadId = mDatabaseRef.push().getKey(); assert uploadId != null; mDatabaseRef.child(uploadId).setValue(upload); } }); - 临时调试规则(仅测试用):若问题仍存在,可临时为Storage规则添加时间限制(如
allow read, write if request.time < timestamp.date(2025, 1, 1);),确认是否为规则生效延迟导致,调试完成后需恢复安全规则。 - 检查网络状态:确保设备网络连接稳定,网络波动可能导致权限校验请求失败。
内容的提问来源于stack exchange,提问作者junior
相关产品推荐
相关产品推荐

