Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从Firebase中删除数据时应用程序崩溃_Android_Firebase_Firebase Realtime Database - Fatal编程技术网

Android 从Firebase中删除数据时应用程序崩溃

Android 从Firebase中删除数据时应用程序崩溃,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我正在为我的应用程序开发事件功能,我已经被这个bug困扰了两天 总之,我登录到应用程序并从Firebase中检索一个eventid,我将其设置为静态User.eventid。当应用程序切换到MainActivity时,静态User.eventid用于决定使用哪个片段:ViewEventsFragment或DefaultEventFragment(带2个按钮的空片段)如果User.eventid=“null”,则转到默认事件片段,否则转到查看事件片段 最初,用户处于事件中,因此user.event

我正在为我的应用程序开发事件功能,我已经被这个bug困扰了两天

总之,我登录到应用程序并从Firebase中检索一个eventid,我将其设置为静态User.eventid。当应用程序切换到MainActivity时,静态User.eventid用于决定使用哪个片段:ViewEventsFragment或DefaultEventFragment(带2个按钮的空片段)如果User.eventid=“null”,则转到默认事件片段否则转到查看事件片段

最初,用户处于事件中,因此user.eventid=“LyfLmM…”因此主活动将用户带到ViewEventsFragment。现在,在ViewEventsFragment中,我可以选择删除事件。执行此操作后,我将更新firebase eventid=“null”以供将来登录并更新要在MainActivity中使用的静态用户。eventid=“null”。然后启动意图并将用户带到MainActivity,应用程序将根据user.eventid决定切换到哪个片段。因为我刚刚更改了静态用户.eventid=“null”,所以应该将我带到DefaultEventsActivity

但这不起作用,我的应用程序反而崩溃了。我包括了从头到尾的代码和错误日志

LoginActivity.class

// Retrieve information about the user from Firebase. One important field is eventid which represents 
// the event that the user is part of. If eventid=="null", then the user is not in any event.

JSONObject obj = new JSONObject(s);
eventid = obj.getJSONObject(id).getString("eventid");
User.eventid = eventid;
...
startActivity(new Intent(SignIn.this, MainActivity.class));
 // Once the user is taken to MainActivity, there is a bottom navigation that loads a fragment 
 // depending on the User.eventid retrieved in Login. If the user is an event, take them to 
 // ViewEventsFragment. if user is NOT in event, take them to DefaultEventsFragment

 @Override
 public boolean onNavigationItemSelected(@NonNull MenuItem item) {
     Fragment fragment;
     switch (item.getItemId()) {
                case R.id.event_button:

                    Log.i("ViewEventsFragment", "MainActivity: "+User.eventid);

                    if(User.eventid.equals("null")) {
                        fragment = fragmentA;
                    }
                    else {
                        fragment = fragmentB;
                    }
                    break;
            ...
            fragmentManager.beginTransaction().replace(R.id.frame_layout, fragment).commit();
            return true;
        }
    });
主课

// Retrieve information about the user from Firebase. One important field is eventid which represents 
// the event that the user is part of. If eventid=="null", then the user is not in any event.

JSONObject obj = new JSONObject(s);
eventid = obj.getJSONObject(id).getString("eventid");
User.eventid = eventid;
...
startActivity(new Intent(SignIn.this, MainActivity.class));
 // Once the user is taken to MainActivity, there is a bottom navigation that loads a fragment 
 // depending on the User.eventid retrieved in Login. If the user is an event, take them to 
 // ViewEventsFragment. if user is NOT in event, take them to DefaultEventsFragment

 @Override
 public boolean onNavigationItemSelected(@NonNull MenuItem item) {
     Fragment fragment;
     switch (item.getItemId()) {
                case R.id.event_button:

                    Log.i("ViewEventsFragment", "MainActivity: "+User.eventid);

                    if(User.eventid.equals("null")) {
                        fragment = fragmentA;
                    }
                    else {
                        fragment = fragmentB;
                    }
                    break;
            ...
            fragmentManager.beginTransaction().replace(R.id.frame_layout, fragment).commit();
            return true;
        }
    });
假设用户是事件的一部分。然后我们加载:

ViewEventsFragment.java

// In this fragment, the user is part of an event. This means that User.eventid is NOT "null" and 
// user was redirected here from MainActivity. So first pull all the
// data from firebase to populate the fields

Firebase.setAndroidContext(getActivity());
pullFirebaseData();

// Pull data from firebase and populate fields
// This function should only be called if eventid is NOT null
// But for some reason, it's being called while it's null and gets an error
public void pullFirebaseData(){

    eventid = User.eventid;    
    if((eventid==null) || (eventid.equals("null"))){
        User.eventid = "null";
        startActivity(new Intent(getActivity(), MainActivity.class));
    }  

    Firebase reference = new Firebase("https://...firebaseio.com/events");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            **Line144** name = dataSnapshot.child(eventid).child("eventName").getValue().toString();
            date = dataSnapshot.child(eventid).child("eventDate").getValue().toString();
            time = dataSnapshot.child(eventid).child("eventTime").getValue().toString();
            ...
 }

// Suppose now user wants to delete the event. 
leaveGroupButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // (1) First update Firebase by changing each users eventid to "null". This works. 
            // (2) Now, change User.eventid="null" since user is leaving the event and switch to 
            //     MainActivity. Since the User.eventid="null", the user SHOULd be taken to 
            //     DefaultEventsFragment and NOT back here. 
            // (3) Finally, delete the event from Firebase

                (1) changeAllUserFirebase();
                (2) User.eventid = "null"
                    startActivity(new Intent(getActivity(), MainActivity.class));
                (3) deleteEvent();
            }
        }
    });

// Remove the entire event from Firebase
public void deleteEvent(){
    Firebase reference = new Firebase("https://grouptracker-ef84c.firebaseio.com/events");
    reference.child(User.eventid).removeValue();
}
现在问题开始了。从日志中可以看出,我正在MainActivity中成功地获取eventid并切换到ViewEventFragment。现在,当我尝试删除它时,它会将我带回到ViewEventsFragments,而实际上它会将我带到MainActivity

2020-01-15 17:40:15.514 18350-18350/com.package.appname I/ViewEventsFragment: MainActivity: -LyfLmMmO1mkB0gvB9P7

2020-01-15 16:38:24.905 17166-17166/com.package.appname E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.package.appname, PID: 17166
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
    at com.package.appname.Fragments.ViewEventsFragment$4.onDataChange(ViewEventsFragment.java:144)
    at com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:56)
    at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
    at com.firebase.client.core.view.EventRaiser$1.run(EventRaiser.java:38)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
因此,我通过删除deleteEvent()对其进行了测试,结果非常理想。我切换到MainACtivity==>DefaultEventFragment。现在我不明白为什么从firebase中删除事件会使我的应用程序崩溃

尝试:因此我尝试将deleteEvent()函数移到Main。因此,一旦用户离开事件,它就会从ViewEventsFragment转到Main。然后,它主要应该删除事件。然而,该应用程序只是返回到ViewEventsFragment并崩溃。不确定是什么原因导致它强制转到ViewEventsFragment。

“当您使用reference.addValueEventListener注册侦听器时,它将在每次侦听的数据更改时调用onDataChange,包括删除该数据时,这意味着将使用null调用它。您应该处理数据丢失的可能性,或者在使用removeEventListener删除数据并传入ValueEventListener的同一实例之前注销侦听器。”

-来自Reddit的汉堡包


由于我正在删除数据,我的侦听器总是在读取新的更改,并且随着数据的消失,它正在获取一些不存在的内容。基于上述逻辑,我重新构造了代码并创建了一个新的侦听器:

final Firebase reference = new Firebase("https://....firebaseio.com/...");

final ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            name = dataSnapshot.child(eventid).child("eventName").getValue().toString();
            ...
            nameTextView.setText(name);
            ...
        }
    };
    // Here, I'm registering the listener
    reference.addValueEventListener(eventListener);
}

// *IMPORTANT*
leaveGroupButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           ...
           // I'm done with the listener so now I'm removing it
           reference.removeEventListener(eventListener);                 
        }
}

这一行的位置是
ViewEventsFragment.java:144
?错误在这一行,带有
toString()
请指明发生错误的确切代码行。我用这些行进行了更新。代码甚至不应该转到这一行,因为我正在删除事件并调用意图切换到另一个活动。但由于某些原因,它没有转到MainActivity,而是重新加载活动并导致错误。错误是意料之中的因为它试图从不存在的东西中检索字符串。