java - Firebase Firestore 数据检索引发空指针异常?
问题描述
我正在尝试从 firestore 获取实时数据并更新我的 android 应用程序中的类级别对象,但是当执行代码时应用程序崩溃并且当我检查它时显示以下错误:
2021-06-08 16:47:37.569 13632-13632/com.example.railtracker E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.railtracker, PID: 13632
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at com.example.railtracker.Acitivity.TrainLiveTrackViewActivity$1.onEvent(TrainLiveTrackViewActivity.java:80)
at com.example.railtracker.Acitivity.TrainLiveTrackViewActivity$1.onEvent(TrainLiveTrackViewActivity.java:69)
at com.google.firebase.firestore.DocumentReference.lambda$addSnapshotListenerInternal$2$DocumentReference(DocumentReference.java:504)
at com.google.firebase.firestore.-$$Lambda$DocumentReference$GF131yLOtm0PQYErAZvV1mYKmvw.onEvent(Unknown Source:6)
at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0$AsyncEventListener(AsyncEventListener.java:42)
at com.google.firebase.firestore.core.-$$Lambda$AsyncEventListener$DNkggu2LY54oguDvcp-QtRg6Sfg.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
我检查了将数据打印到终端并正确显示,但是当我尝试将其分配给变量时,应用程序崩溃了。请帮我解决这个问题。提前致谢。
我的代码:
package com.example.railtracker.Acitivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.IntentService;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import com.example.railtracker.Adapter.StopViewAdapter;
import com.example.railtracker.DTO.TrainDTO;
import com.example.railtracker.DTO.TrainInfoDTO;
import com.example.railtracker.R;
import com.example.railtracker.Util.FetchLocationIntentService;
import com.github.vipulasri.timelineview.TimelineView;
import com.google.android.gms.common.logging.Logger;
import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.snackbar.Snackbar;
import com.google.api.Logging;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
public class TrainLiveTrackViewActivity extends AppCompatActivity {
private static final String TAG= TrainLiveTrackViewActivity.class.getSimpleName();
private RecyclerView stopsView;
private Toolbar toolbar;
private TrainDTO train;
private LocationReceiver locationReceiver;
private Location lastLocation;
private String zipCode;
private TrainInfoDTO trainInfoDTO=new TrainInfoDTO();
private final String RESULT_DATA="RESULT_DATA";
private final String COLUMN="trains";
double sample;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_train_live_track_view);
setUpView();
locationReceiver=new LocationReceiver(new Handler());
loadRealTimeData();
}
private void loadRealTimeData()
{
try{
DocumentReference db= FirebaseFirestore.getInstance().collection(COLUMN).document( String.valueOf(train.getTrainId()));
db.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
if(error != null){
Log.e(TAG,error.getMessage());
error.printStackTrace();
}
if(value != null && value.exists()){
trainInfoDTO.setTrainId((int) value.get(getResources().getString(R.string.train_id)));
trainInfoDTO.setLat((double)value.get(getResources().getString(R.string.latitude)));
trainInfoDTO.setLon((double)value.get(getResources().getString(R.string.longitude)));
trainInfoDTO.setPassengerCount((int)value.get(getResources().getString(R.string.passenger_count)));
trainInfoDTO.setSeatingCapacity(train.getSeatingCapacity());
System.out.println(value.getData());
}
else{
showSnackbar(getResources().getString(R.string.no_train_data));
}
}
});
}catch (Exception e){
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
}
private void showSnackbar(String text){
View container=findViewById(android.R.id.content);
if(container != null){
Snackbar.make(container,text,Snackbar.LENGTH_LONG).show();
}
}
private void setUpView() {
toolbar=findViewById(R.id.ToolBarMain);
stopsView=findViewById(R.id.stops_rv);
Intent intent=getIntent();
train=(TrainDTO)intent.getSerializableExtra("train");
StopViewAdapter adapter=new StopViewAdapter(train.getCurrentShift().getStops(),this);
stopsView.setAdapter(adapter);
stopsView.setLayoutManager(new LinearLayoutManager(this));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(train.getName());
}
private void startIntentService()
{
Intent intent= new Intent(this, FetchLocationIntentService.class);
intent.putExtra("LocationReceiver",locationReceiver);
intent.putExtra("LastLocation",lastLocation);
startService(intent);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
private class LocationReceiver extends ResultReceiver {
/**
* Create a new ResultReceive to receive results. Your
* {@link #onReceiveResult} method will be called from the thread running
* <var>handler</var> if given, or from an arbitrary thread if null.
*
* @param handler
*/
public LocationReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
zipCode= resultData.getString(RESULT_DATA);
}
}
}
解决方案
我能够在上述情况下找出问题所在。我在 firestore 中访问的文档有一个内部 Map,其中包含它的属性,因此抛出空指针异常,因为我直接尝试从文档中访问属性。我做了以下工作:
Map<String,Object> map=new HashMap<>();
map=(Map)value.get(String.valueOf(train.getTrainId()));
trainInfoDTO.setLat((double) map.get(getResources().getString(R.string.latitude)));
推荐阅读
- ios - 多次调用 setViewControllers(direction:animated:completion:) 时崩溃
- javascript - 不和谐.js | 如何获取用户的输入并为其发送消息?
- nginx - 如何清除 nginx 中的 keys_zone 内存
- java - 将 Object 的对象变成不同类型的对象?
- ios - 如何通过单击添加来添加一个单元格,该单元格将采用 TextField 值并在该表格视图中创建一个包含该文本的单元格,如下图 Swift/Obj-C 中的图像?
- assembly - 尝试在 x86 汇编中进行乘法运算,使用 rax、rdi、rsi 和 rcx 寄存器
- flutter - Flutter 应用程序无法调用 API。未处理的异常:键入“列表”
' 不是类型 'Map 的子类型 ' - go - ANTLR4 内存使用
- php - Laravel route() 为 localhost 返回错误的 url
- python-3.x - Django forms.ModelForm slugfield db_index=True