Firestore返回null对象引用 点击joinBtn跳转EventDetail闪退排查

我尝试访问EventDetail Activity时,应用会持续退回到MainActivity。该问题是我参照此前帖子给出的建议添加joinBtn.setOnClickListener并修改代码后出现的。
请问各位能否帮忙解决该问题?提前感谢。
public class EventDetail extends AppCompatActivity { private static final String TAG = "DetailActivity"; EventModel event; private TextView textViewEName, textViewEVenue, textViewEDate, textViewEDesc; private Button joinBtn; private FirebaseFirestore fStore; private FirebaseUser user; private FirebaseAuth fAuth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_event_detail); Log.d(TAG, "onCreate: Started."); fStore = FirebaseFirestore.getInstance(); user= FirebaseAuth.getInstance().getCurrentUser(); textViewEName = (TextView)findViewById(R.id.textEventNameDetail); textViewEDate = (TextView)findViewById(R.id.textEventDateDetail); textViewEVenue = (TextView)findViewById(R.id.textEventVenueDetail); textViewEDesc = (TextView)findViewById(R.id.textEventDescDetail); joinBtn=findViewById(R.id.joinBtn); textViewEName.setText(getIntent().getStringExtra("eventName").toString()); textViewEDate.setText(getIntent().getStringExtra("eventDate").toString()); textViewEVenue.setText(getIntent().getStringExtra("eventVenue").toString()); textViewEDesc.setText(getIntent().getStringExtra("eventDesc").toString()); //当特定事件卡片被点击时 joinBtn.setOnClickListener(new View.OnClickListener() { //创建AddEvent对象a以访问AddEvent中的变量 AddEvent a = new AddEvent(); @Override public void onClick(View v) { FirebaseFirestore rootRef = FirebaseFirestore.getInstance(); CollectionReference collRef= rootRef.collection("users"); Map<String, Object> update = new HashMap<>(); update.put("eventDocId", a.eventDocId); DocumentReference docId = collRef.document(user.getUid()); docId.update("saved_event", update).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull @NotNull Task<Void> task) { Log.d(TAG, "Update complete."); } }); } }); } }
错误是在添加如下代码后出现的:
joinBtn.setOnClickListener(new View.OnClickListener() { //创建AddEvent对象a以访问AddEvent中的变量 AddEvent a = new AddEvent(); @Override public void onClick(View v) { FirebaseFirestore rootRef = FirebaseFirestore.getInstance(); CollectionReference collRef= rootRef.collection("users"); Map<String, Object> update = new HashMap<>(); update.put("eventDocId", a.eventDocId); DocumentReference docId = collRef.document(user.getUid()); docId.update("saved_event", update).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull @NotNull Task<Void> task) { Log.d(TAG, "Update complete."); } }); } });
2021-08-27 08:24:40.590 18531-18531/com.example.myvolunteer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myvolunteer, PID: 18531
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myvolunteer/com.example.myvolunteer.EventDetail}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.firestore.CollectionReference com.google.firebase.firestore.FirebaseFirestore.collection(java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3792)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8512)
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:1139)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.firestore.CollectionReference com.google.firebase.firestore.FirebaseFirestore.collection(java.lang.String)' on a null object reference
at com.example.myvolunteer.AddEvent.(AddEvent.java:40)
at com.example.myvolunteer.EventDetail$1.(EventDetail.java:63)
at com.example.myvolunteer.EventDetail.onCreate(EventDetail.java:61)
at android.app.Activity.performCreate(Activity.java:8198)
at android.app.Activity.performCreate(Activity.java:8182)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3765)
崩溃由空指针异常触发,核心问题是你在OnClickListener中手动通过new AddEvent()实例化了Activity组件。Activity是安卓系统管控的组件,不能手动创建实例,否则其内部的生命周期回调(onCreate等)不会执行,AddEvent类第40行的FirebaseFirestore初始化逻辑没有运行,调用collection方法时实例为空,直接抛出异常。
- 不要手动实例化AddEvent获取eventDocId,在列表页跳转EventDetail时,将当前点击事件对应的eventDocId作为额外参数通过Intent传递到EventDetail即可
- 在EventDetail中读取传递过来的eventDocId,直接在点击事件中使用
代码修改示例
- 列表页跳转逻辑新增传参:
// 列表页点击事件卡片跳转EventDetail的原有逻辑,新增传递eventDocId Intent intent = new Intent(当前列表页上下文, EventDetail.class); // 保留原有参数 intent.putExtra("eventName", event.getName()); intent.putExtra("eventDate", event.getDate()); intent.putExtra("eventVenue", event.getVenue()); intent.putExtra("eventDesc", event.getDesc()); // 新增传递当前事件的文档ID intent.putExtra("eventDocId", 当前点击事件对应的文档ID); startActivity(intent);
- EventDetail类修改点击事件逻辑:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_event_detail); // 保留原有初始化逻辑 fStore = FirebaseFirestore.getInstance(); user= FirebaseAuth.getInstance().getCurrentUser(); // 读取传递过来的eventDocId String eventDocId = getIntent().getStringExtra("eventDocId"); textViewEName = (TextView)findViewById(R.id.textEventNameDetail); // 保留原有控件赋值逻辑 textViewEName.setText(getIntent().getStringExtra("eventName").toString()); textViewEDate.setText(getIntent().getStringExtra("eventDate").toString()); textViewEVenue.setText(getIntent().getStringExtra("eventVenue").toString()); textViewEDesc.setText(getIntent().getStringExtra("eventDesc").toString()); joinBtn=findViewById(R.id.joinBtn); // 修改后的点击事件 joinBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FirebaseFirestore rootRef = FirebaseFirestore.getInstance(); CollectionReference collRef= rootRef.collection("users"); Map<String, Object> update = new HashMap<>(); update.put("eventDocId", eventDocId); DocumentReference docId = collRef.document(user.getUid()); docId.update("saved_event", update).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull @NotNull Task<Void> task) { Log.d(TAG, "Update complete."); } }); } }); }
内容的提问来源于stack exchange,提问作者PI PI NAN

