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

Android聊天应用Cloud Firestore数据写入失败问题排查

Android聊天应用Cloud Firestore数据写入失败问题修复

问题现象

开发Android聊天应用时,已编写用户资料保存代码,但Cloud Firestore中无对应Users集合数据,导致RecyclerView无法从Firestore拉取用户列表完成渲染。
Cloud FireStore控制台截图

核心原因

代码存在异步流程时序错误,是导致数据无法写入的根因:

  • 保存按钮点击逻辑中,调用sendDataForNewUser()后立刻执行页面跳转并finish当前Activity,但图片上传到Storage、获取图片下载URI、写入Firestore全是异步回调操作,此时Activity被销毁,异步任务被系统终止,根本执行不到Firestore写入逻辑。
  • Firestore写入、图片上传、URI获取等操作均未添加失败回调,发生权限错误、网络错误、空指针异常时无任何提示,无法感知失败原因。
  • 图片解码逻辑未做空判断,一旦图片读取失败触发空指针,会直接中断整个保存流程。

修复方案

  • 调整页面跳转时机:移除保存按钮点击事件中立即跳转、关闭页面的逻辑,等所有异步流程(实时库写入、图片上传、Firestore写入)全部执行成功后,再执行页面跳转。
  • 补全所有异步操作的失败回调:为每个Firebase异步任务添加失败监听,弹出错误提示方便定位问题,出错时及时关闭加载进度条避免卡死。
  • 增加空值容错判断:图片解码后增加bitmap空校验,避免空指针崩溃中断流程。

修复后核心代码

保存按钮点击逻辑

msaveprofile.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        name = mgetusername.getText().toString();
        if(name.isEmpty()){
            Toast.makeText(getApplicationContext(), "Name is Empty", Toast.LENGTH_SHORT).show();
        } else if(imagepath == null){
            Toast.makeText(getApplicationContext(), "Image is Empty", Toast.LENGTH_SHORT).show();
        } else {
            mprogressbarofsetprofile.setVisibility(View.VISIBLE);
            sendDataForNewUser();
            // 移除此处的立即跳转、finish、进度条隐藏逻辑,等所有异步完成后再执行
        }
    }
});

图片上传方法

private void sendImagetoStorage() {
    StorageReference imageref = storageReference.child("Images").child(firebaseAuth.getUid()).child("Profile Pic");
    Bitmap bitmap = null;
    try {
        bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imagepath);
    } catch (IOException e) {
        e.printStackTrace();
        mprogressbarofsetprofile.setVisibility(View.INVISIBLE);
        Toast.makeText(getApplicationContext(), "Failed to read image", Toast.LENGTH_SHORT).show();
        return;
    }
    // 新增bitmap空判断
    if (bitmap == null) {
        mprogressbarofsetprofile.setVisibility(View.INVISIBLE);
        Toast.makeText(getApplicationContext(), "Failed to parse image", Toast.LENGTH_SHORT).show();
        return;
    }
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 25, byteArrayOutputStream);
    byte[] data = byteArrayOutputStream.toByteArray();

    UploadTask uploadTask = imageref.putBytes(data);
    uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            imageref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    ImageUriAcessToken = uri.toString();
                    Toast.makeText(getApplicationContext(), "URI get Success", Toast.LENGTH_SHORT).show();
                    sendDataTocloudFireStore();
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    mprogressbarofsetprofile.setVisibility(View.INVISIBLE);
                    Toast.makeText(getApplicationContext(), "URI get Failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
            Toast.makeText(getApplicationContext(), "Image is uploaded", Toast.LENGTH_SHORT).show();
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            mprogressbarofsetprofile.setVisibility(View.INVISIBLE);
            Toast.makeText(getApplicationContext(), "Image upload Failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

Firestore写入方法

private void sendDataTocloudFireStore() {
    DocumentReference documentReference = firebaseFirestore.collection("Users").document(firebaseAuth.getUid());
    Map<String, Object> userdata = new HashMap<>();
    userdata.put("name", name);
    userdata.put("image", ImageUriAcessToken);
    userdata.put("uid", firebaseAuth.getUid());
    userdata.put("status", "Online");

    documentReference.set(userdata)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                mprogressbarofsetprofile.setVisibility(View.INVISIBLE);
                Toast.makeText(getApplicationContext(), "User profile set Successfully", Toast.LENGTH_SHORT).show();
                // 所有流程执行成功后再跳转页面
                Intent intent = new Intent(ControlDesk.this, Chat.class);
                startActivity(intent);
                finish();
            }
        })
        // 新增失败回调
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                mprogressbarofsetprofile.setVisibility(View.INVISIBLE);
                Toast.makeText(getApplicationContext(), "Firestore write Failed: " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
}

额外配置检查

确认Firebase控制台Firestore安全规则配置正确,测试阶段可使用如下规则允许已登录用户写入自己的资料:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /Users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:06:25