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

将扫描文本写入Firebase实时数据库时遇空指针异常求助

问题:Firebase实时数据库写入时触发空指针异常

我开发了一个Android OCR项目,支持拍照/从相册选图,通过裁剪库提取目标区域后识别文本,识别结果能正常显示,但无法写入Firebase Realtime Database。数据库连接已配置成功,问题出在getTextFromImage方法的数据库写入环节。

相关代码(MainActivity.java)

package com.example.myapplication;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.text.TextBlock;
import com.google.android.gms.vision.text.TextRecognizer;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.OAuthCredential;
import com.google.firebase.auth.OAuthProvider;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.theartofdev.edmodo.cropper.CropImage;
import com.theartofdev.edmodo.cropper.CropImageView;

    private void getTextFromImage(Bitmap bitmap) {
        TextRecognizer recognizer = new TextRecognizer.Builder(this).build();

        if (!recognizer.isOperational()) {
            Toast.makeText(MainActivity.this, "Error Occurred!!", Toast.LENGTH_SHORT).show();
        } else {
            Frame frame = new Frame.Builder().setBitmap(bitmap).build();
            SparseArray<TextBlock> textBlockSparseArray = recognizer.detect(frame);
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < textBlockSparseArray.size(); i++) {
                textBlock = textBlockSparseArray.valueAt(i);
                stringBuilder.append(textBlock.getValue());
                stringBuilder.append("\n");
            }
            textView_data.setText(stringBuilder.toString());

            FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

            String uid = textBlock.getValue();
            System.out.println("okutulan yazı 2: "+uid);
            ReadWriteUserDetails writeUserDetails = new ReadWriteUserDetails(uid);
            DatabaseReference referenceProfile = FirebaseDatabase.getInstance().getReference("Cropped all texts");
            if (firebaseUser != null) {
                referenceProfile = referenceProfile.child(firebaseUser.getUid());
            }
            System.out.println("hata verdi 2");

            referenceProfile.child(firebaseUser.getUid()).setValue(writeUserDetails).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    Toast.makeText(MainActivity.this, "Data is written on the database successfully", Toast.LENGTH_LONG).show();
                }
            });

            button_capture.setText("Retake");
            button_copy.setVisibility(View.VISIBLE);
        }
    }
}

控制台报错信息

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 28303
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=203, result=-1, data=Intent {  launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 }(has extras) }} to activity {com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4520)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563)
        at android.app.ActivityThread.-wrap22(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
        at com.example.myapplication.MainActivity.getTextFromImage(MainActivity.java:144)
        at com.example.myapplication.MainActivity.onActivityResult(MainActivity.java:104)
        at android.app.Activity.dispatchActivityResult(Activity.java:7280)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4516)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563) 
        at android.app.ActivityThread.-wrap22(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6776) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 

解决方案

问题分析

  1. 空指针直接原因:代码仅在referenceProfile赋值时检查firebaseUser != null,但后续调用referenceProfile.child(firebaseUser.getUid())未判空,用户未登录时firebaseUser为null,触发空指针。
  2. 额外问题:
    • 循环结束后textBlock可能指向最后一个TextBlock,若识别结果为空会导致uid赋值出错
    • 数据库节点路径重复添加用户UID,导致层级错误

修复代码

private void getTextFromImage(Bitmap bitmap) {
    TextRecognizer recognizer = new TextRecognizer.Builder(this).build();

    if (!recognizer.isOperational()) {
        Toast.makeText(MainActivity.this, "Error Occurred!!", Toast.LENGTH_SHORT).show();
        return;
    }

    Frame frame = new Frame.Builder().setBitmap(bitmap).build();
    SparseArray<TextBlock> textBlockSparseArray = recognizer.detect(frame);
    StringBuilder stringBuilder = new StringBuilder();
    String recognizedText = "";
    for (int i = 0; i < textBlockSparseArray.size(); i++) {
        TextBlock textBlock = textBlockSparseArray.valueAt(i);
        stringBuilder.append(textBlock.getValue());
        stringBuilder.append("\n");
    }
    recognizedText = stringBuilder.toString();
    textView_data.setText(recognizedText);

    // 先检查用户是否登录
    FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
    if (firebaseUser == null) {
        Toast.makeText(MainActivity.this, "请先登录账号", Toast.LENGTH_SHORT).show();
        button_capture.setText("Retake");
        button_copy.setVisibility(View.VISIBLE);
        return;
    }

    ReadWriteUserDetails writeUserDetails = new ReadWriteUserDetails(recognizedText);
    DatabaseReference referenceProfile = FirebaseDatabase.getInstance().getReference("Cropped all texts");
    // 节点路径修正:直接使用用户UID作为子节点,避免重复添加
    referenceProfile.child(firebaseUser.getUid()).setValue(writeUserDetails)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Toast.makeText(MainActivity.this, "数据已成功写入数据库", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, "数据写入失败:" + task.getException().getMessage(), Toast.LENGTH_LONG).show();
                    }
                }
            });

    button_capture.setText("Retake");
    button_copy.setVisibility(View.VISIBLE);
}

关键修复点

  • 提前检查firebaseUser是否为null,未登录时提示并终止后续操作
  • 用recognizedText变量存储完整识别结果,避免依赖循环后的textBlock对象
  • 修正数据库节点路径,避免重复添加用户UID
  • 在onComplete中判断任务是否成功,添加失败提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:45:16