Android Cloud FireStore数据读取异常:获取数据为null求助排查
问题排查与解决方案
我一眼就看出问题所在啦——这是异步操作的时序问题导致你拿到null值!
问题根源
Firestore的get()和addSnapshotListener都是异步执行的方法:你调用它们后,代码会立刻继续往下执行,不会等待Firestore从云端返回数据。而你在代码最后一行的id_customer = customers.get(0).getId_customer();,是在异步回调(onComplete/onEvent)执行前就运行了,这时候customers要么还没被初始化,要么还是空集合,自然会拿到null甚至抛出空指针异常。
代码逻辑修正方案
因为你只需要单条数据,完全不用循环遍历整个集合,下面给你两种更高效的修正方式:
方案1:已知文档ID时,直接获取单条文档(推荐)
如果知道你要获取的文档ID(比如截图里的那个文档ID),直接通过document()方法定位,效率更高:
private void getCustomer(){ // 替换成你实际的文档ID String targetDocId = "your-document-id-from-screenshot"; firestoreDB.collection("customer").document(targetDocId) .get() .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() { @Override public void onComplete(@NonNull Task<DocumentSnapshot> task) { if (task.isSuccessful()) { DocumentSnapshot doc = task.getResult(); if (doc.exists()) { // 数据已成功获取,在这里处理 Customer customer = doc.toObject(Customer.class); customer.setId_customer(doc.getId()); id_customer = customer.getId_customer(); // 后续操作(比如更新UI)也必须放在这里 } else { Log.d(TAG, "目标文档不存在"); } } else { Log.d(TAG, "获取数据失败: ", task.getException()); } } }); }
方案2:未知文档ID,仅需第一条数据
如果确实需要从集合中取第一条数据,必须把数据处理逻辑放在异步回调内部:
private void getCustomer(){ firestoreDB.collection("customer") .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { customers = new ArrayList<>(); for (DocumentSnapshot doc : task.getResult()) { Customer customer = doc.toObject(Customer.class); customer.setId_customer(doc.getId()); customers.add(customer); } // 数据已准备好,在这里处理 if (!customers.isEmpty()) { id_customer = customers.get(0).getId_customer(); // 后续操作(比如更新UI)放在这里 } } else { Log.d(TAG, "获取数据失败: ", task.getException()); } } }); // 实时监听的逻辑同样要把数据处理放在回调里 firestoreListener = firestoreDB.collection("customer") .addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) { if (e != null) { Log.e(TAG, "监听失败!", e); return; } customers = new ArrayList<>(); for (DocumentSnapshot doc : documentSnapshots) { Customer customer = doc.toObject(Customer.class); customer.setId_customer(doc.getId()); customers.add(customer); } // 实时更新时的处理逻辑 if (!customers.isEmpty()) { id_customer = customers.get(0).getId_customer(); // 更新UI等操作放在这里 } } }); }
关键提醒
所有依赖Firestore返回数据的逻辑,必须放在异步回调函数内部(比如onComplete或onEvent方法里),绝对不能在回调外部直接访问数据——因为异步操作完成前,数据还没从云端拉取回来,必然会拿到null或空值。
内容的提问来源于stack exchange,提问作者RPH
相关产品推荐
相关产品推荐

