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

Firebase文本与图片上传触发应用崩溃问题求助

解决Firebase上传时的NullPointerException问题

错误根源分析

从Logcat日志可以明确看到,空指针异常出现在uploadPicture方法的imgPath.putFile(uri)这一行,核心原因是:你声明了成员变量imgPath但从未给它赋值,它始终处于null状态。

更关键的是,你在setProfilePicture和setCoverPicture方法里已经正确创建了StorageReference实例,并把它作为参数传给了uploadPicture,但uploadPicture方法完全没用到这个传入的参数,反而去调用了未初始化的imgPath,这直接触发了空指针崩溃。

第一步:修复空指针问题

修改uploadPicture方法,把方法内的imgPath替换成传入的storageReference参数,同时可以删掉多余的imgPath成员变量,避免后续混淆:

public class ProfileUtils { 
    private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance(); 
    private FirebaseAuth firebaseAuth; 
    private StorageReference storageReference; 
    private Map<String, String> userSetupMap; 
    private ProcessStatusObservable processStatusObservable; 
    // 移除多余的imgPath成员变量
    private String userId; 

    public ProfileUtils(){ 
        processStatusObservable = new ProcessStatusObservable(); 
        userSetupMap = new HashMap<>(); 
        firebaseAuth = FirebaseAuth.getInstance(); 
        userId = firebaseAuth.getCurrentUser().getUid(); 
        storageReference = FirebaseStorage.getInstance().getReference(); 
    } 

    private void uploadPicture(String pictureType, Uri uri, StorageReference storageReference){
        // 使用传入的storageReference而非未初始化的imgPath
        storageReference.putFile(uri).addOnCompleteListener(task -> { 
            if(task.isSuccessful()){ 
                Uri imageUri = task.getResult().getDownloadUrl(); 
                userSetupMap.put(pictureType.concat("PictureUrl"), imageUri.toString()); 
            } else{ 
                // 建议添加错误处理,通知观察者上传失败
                processStatusObservable.setStatus(ProcessStatus.NEW_USER_PROFILE_SETUP_FAILED);
            } 
        }); 
    } 

    // 其余方法保持不变...
}

第二步:解决异步上传的时序问题

修复空指针后,还有一个潜在的隐性问题:图片上传是异步操作,如果你直接调用commit(),Firestore的写入可能会先执行,此时图片URL还没被存入userSetupMap,导致用户资料缺少图片地址。

可以通过Firebase的Tasks.whenAll()方法等待所有上传任务完成后,再执行Firestore的写入操作:

public class ProfileUtils { 
    // 添加成员变量保存所有上传任务
    private List<Task<UploadTask.TaskSnapshot>> uploadTasks = new ArrayList<>();
    // ...其他成员变量

    private void uploadPicture(String pictureType, Uri uri, StorageReference storageReference){
        Task<UploadTask.TaskSnapshot> uploadTask = storageReference.putFile(uri).addOnCompleteListener(task -> { 
            if(task.isSuccessful()){ 
                Uri imageUri = task.getResult().getDownloadUrl(); 
                userSetupMap.put(pictureType.concat("PictureUrl"), imageUri.toString()); 
            } else{ 
                processStatusObservable.setStatus(ProcessStatus.NEW_USER_PROFILE_SETUP_FAILED);
            } 
        });
        // 将当前上传任务加入列表
        uploadTasks.add(uploadTask);
    } 

    public void commit(){
        // 等待所有上传任务完成后再执行Firestore写入
        Tasks.whenAll(uploadTasks).addOnCompleteListener(uploadBatchTask -> {
            if(uploadBatchTask.isSuccessful()){
                firebaseFirestore.collection("Users").document(userId)
                    .set(userSetupMap).addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if(task.isSuccessful()){
                                processStatusObservable.setStatus(ProcessStatus.NEW_USER_PROFILE_SETUP_SUCCESS);
                            } else{
                                processStatusObservable.setStatus(ProcessStatus.NEW_USER_PROFILE_SETUP_FAILED);
                            }
                        }
                    });
            } else{
                processStatusObservable.setStatus(ProcessStatus.NEW_USER_PROFILE_SETUP_FAILED);
            }
        });
    } 
}

这样就能确保所有图片上传完成并获取到下载URL后,再把完整的用户资料写入Firestore,避免数据不完整的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:41:30