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

Android Studio中Firestore文档删除失败问题求助

问题:Firestore删除子集合文档时出现空指针崩溃

我是Android Studio新手,开发校园项目的三个标签页(album、notes、files)时,删除Firestore子集合文档出错。项目中图片同时存储在Firebase Storage和Firestore,点击图片查看页的删除按钮后页面跳转,重复操作会崩溃,添加日志无输出,尝试删除Storage文件也报错。

上传代码

private void uploadToFirebase(Uri uri) {
    Log.d("UploadToFirebase", "Starting upload process");
    String caption = uploadCaption.getText().toString();
    final StorageReference imageReference = storageReference.child("Album" + System.currentTimeMillis() + "." + getFileExtension(uri));
    final CollectionReference forAlbum = Utility.getCollectionReferenceForAlbum(courseId);

    imageReference.putFile(uri)
      .addOnSuccessListener(taskSnapshot -> {
        // Get download URL for the uploaded image
        imageReference.getDownloadUrl().addOnSuccessListener(uriResult -> {
          String imageUrl = uriResult.toString();

          DataClass dataClass = new DataClass(imageUrl, caption);

          forAlbum.add(dataClass)
          .addOnSuccessListener(CollectionReference -> {
            progressBar.setVisibility(View.INVISIBLE);
            Toast.makeText(AddtoAlbum.this, "Uploaded", Toast.LENGTH_SHORT).show();
            finish();
          })
          .addOnFailureListener(e -> {
            progressBar.setVisibility(View.INVISIBLE);
            Toast.makeText(AddtoAlbum.this, "Failed to upload image", Toast.LENGTH_SHORT).show();
          });
        });
      })

删除代码

private void deleteImage(String imageUrl) {
  CollectionReference imagesCollectionRef = FirebaseFirestore.getInstance().collection("Albums");
  DocumentReference imageDocRef = imagesCollectionRef.document(imageUrl);

  imageDocRef.delete()
    .addOnSuccessListener(new OnSuccessListener < Void > () {
      @Override
      public void onSuccess(Void aVoid) {
        Toast.makeText(FullImage.this, "Image deleted", Toast.LENGTH_SHORT).show();
        finish();
      }
    })
    .addOnFailureListener(new OnFailureListener() {
      @Override
      public void onFailure(@NonNull Exception e) {
        Toast.makeText(FullImage.this, "Failed to delete image", Toast.LENGTH_SHORT).show();
      }
    });
}

LogCat报错信息

FATAL EXCEPTION: main
Process: com.example.project_acadeamease1, PID: 10281
java.lang.NullPointerException: Provided document path must not be null.
at com.google.firebase.firestore.util.Preconditions.checkNotNull(Preconditions.java: 148)
at com.google.firebase.firestore.CollectionReference.document(CollectionReference.java: 103)
at com.example.project_acadeamease1.Utility.getCollectionReferenceForAlbum(Utility.java: 25)
at com.example.project_acadeamease1.FullImage.deleteImage(FullImage.java: 59)
at com.example.project_acadeamease1.FullImage.access$100(FullImage.java: 20)
at com.example.project_acadeamease1.FullImage$2.onClick(FullImage.java: 51)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java: 188)
at android.os.Handler.dispatchMessage(Handler.java: 106)
at android.os.Looper.loop(Looper.java: 246)
at android.app.ActivityThread.main(ActivityThread.java: 8653)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java: 602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 1130)

问题原因分析

  1. 文档ID匹配错误:上传时调用forAlbum.add(dataClass)让Firestore自动生成文档ID,但删除时用imageUrl(Storage下载链接)作为文档ID查找,完全不匹配,无法定位目标文档。
  2. 空指针根源:报错指向Utility.getCollectionReferenceForAlbum方法,说明调用该方法时传入的courseId为空,导致生成集合引用时路径无效,触发空指针。
  3. 参数传递缺失:跳转图片查看页时,未传递courseId和正确的Firestore文档ID,导致删除时无法定位到正确的集合和文档。

解决方法

1. 修正上传逻辑,保存文档ID

上传成功后获取Firestore自动生成的文档ID,并更新到文档中,方便后续删除:

forAlbum.add(dataClass)
    .addOnSuccessListener(documentReference -> {
        // 获取自动生成的文档ID
        String docId = documentReference.getId();
        // 将文档ID存入当前文档
        documentReference.update("documentId", docId)
            .addOnSuccessListener(aVoid -> {
                progressBar.setVisibility(View.INVISIBLE);
                Toast.makeText(AddtoAlbum.this, "Uploaded", Toast.LENGTH_SHORT).show();
                finish();
            });
    })

2. 完善页面参数传递

跳转图片查看页时,传递文档ID、图片URL和courseId:

Intent intent = new Intent(AddtoAlbum.this, FullImage.class);
intent.putExtra("DOC_ID", docId);
intent.putExtra("IMAGE_URL", imageUrl);
intent.putExtra("COURSE_ID", courseId);
startActivity(intent);

3. 修正删除代码,定位正确文档

在FullImage页面先获取传递的参数,再执行删除操作,同时删除Storage中的图片:

// 先在onCreate中获取参数
String courseId = getIntent().getStringExtra("COURSE_ID");
String docId = getIntent().getStringExtra("DOC_ID");
String imageUrl = getIntent().getStringExtra("IMAGE_URL");

// 修正后的删除方法
private void deleteImage(String docId, String imageUrl, String courseId) {
    // 确保参数不为空
    if (docId == null || courseId == null) {
        Toast.makeText(this, "Missing required data", Toast.LENGTH_SHORT).show();
        return;
    }

    // 获取正确的集合引用
    CollectionReference albumCollection = Utility.getCollectionReferenceForAlbum(courseId);
    DocumentReference imageDocRef = albumCollection.document(docId);

    imageDocRef.delete()
        .addOnSuccessListener(aVoid -> {
            // Firestore删除成功后,删除Storage中的图片
            deleteFromStorage(imageUrl);
            Toast.makeText(FullImage.this, "Image deleted", Toast.LENGTH_SHORT).show();
            finish();
        })
        .addOnFailureListener(e -> {
            Toast.makeText(FullImage.this, "Failed to delete image: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        });
}

// 删除Storage文件的方法
private void deleteFromStorage(String imageUrl) {
    if (imageUrl == null) return;
    StorageReference storageRef = FirebaseStorage.getInstance().getReferenceFromUrl(imageUrl);
    storageRef.delete()
        .addOnSuccessListener(aVoid -> Log.d("DeleteStorage", "File deleted successfully"))
        .addOnFailureListener(e -> Log.e("DeleteStorage", "Failed to delete file", e));
}

4. 增加参数校验

在删除按钮点击事件中添加参数校验,避免空指针:

// 删除按钮点击事件
new AlertDialog.Builder(this)
    .setTitle("Delete")
    .setMessage("Are you sure to delete this image?")
    .setPositiveButton("Yes", (dialog, which) -> {
        Log.d("DeleteCheck", "docId: " + docId + ", courseId: " + courseId + ", imageUrl: " + imageUrl);
        if (docId != null && courseId != null && imageUrl != null) {
            deleteImage(docId, imageUrl, courseId);
        } else {
            Toast.makeText(FullImage.this, "Missing data, cannot delete", Toast.LENGTH_SHORT).show();
        }
    })
    .setNegativeButton("No", null)
    .show();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:17:09