简体   繁体   中英

Android Firebase valueEventListener causing app to crash

App Explanation

My application retrieves data from a Firebase Database. Firstly, I am pushing a java object to the database correctly, and can retrieve the data without any issue, using the addListenerForSingleValueEvent method in the Fragments onActivityCreated. In total I have 4 fragments which are implemented using a ViewPager. Three of the fragments contain a ListView each, with different types of data being shown in each. The data is downloaded and added to a ListView for each fragment. When a user clicks on a ListView item, a dialog is displayed that contains and edit text. The user enters a value and clicks save. The value entered by the user is pushed to the database with additional parameters eg date, jobID etc. as another Java object (Status.class) When I push this object I am using a DatabaseReference.CompletionListener, and inside the onComplete method I am performing some actions. One of these actions is to recreate the Fragment's Parent activity to allow the UI to be updated based on an items actioned state. I didn't think it was very efficient to recreate the Parent Activity every time one item in the ListView is actioned. So I decided to use a ValueEventListener instead of SingleValueEventListener which should update the ListView for that item. The ValueEventListener works fine to create the ListView, but when the user clicks on any ListView item for the first time, and they enter a value and click save, the app then crashes with the following error below. When the app is restarted, the item in the ListView is now displayed differently as it has been actioned. Clicking on any item and saving the data from then on works fine. It is only when the user saves data for the first time that the app crashes. I am a loss as to what is causing it.

Error

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
   at android.view.LayoutInflater.from(LayoutInflater.java:233)
   at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:181)
   at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:166)
   at com.project.nolan.john.application.IOAdapter.<init>(IOAdapter.java:0)
   at com.project.nolan.john.application.Fragment_Sensors.makeListViewFromDataSnapshot(Fragment_Sensors.java:178)
   at com.project.nolan.john.application.Fragment_Sensors.access$000(Fragment_Sensors.java:58)
   at com.project.nolan.john.application.Fragment_Sensors$1.onDataChange(Fragment_Sensors.java:141)
   at com.google.android.gms.internal.zzegf.zza(Unknown Source)
   at com.google.android.gms.internal.zzeia.zzbyc(Unknown Source)
   at com.google.android.gms.internal.zzeig.run(Unknown Source)
   at android.os.Handler.handleCallback(Handler.java:751)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6682)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)*

Value Event Listener in Fragment's onActivityCreated

 databaseReference.addValueEventListener(new ValueEventListener()
    {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot)
        {
            mPointsList = new ArrayList<>();

            for (DataSnapshot ds : dataSnapshot.getChildren())
            {
                IO_Point io = ds.getValue(IO_Point.class);

                if(io != null)
                {
                    if(io.getSiteUID().equals(mSiteUID) && io.getType().equals("S"))
                    {
                        mPointsList.add(io);
                    }
                }
            }

            if(mSensors_IOPointList != null)
            {
                mListAdapter = new IOAdapter(getActivity(), mPointsList);
            }

            mListView.setAdapter(mListAdapter);
        }

        @Override
        public void onCancelled(DatabaseError databaseError)
        {

        }
    });

If you need any more information/code let me know and I will edit my question.

Edit

IO_Point.class

    public class IO_Point
{
    private String type;
    private String lan;
    private String os;
    private String ionum;
    private String label;
    private String siteUID;
    private Boolean actioned;
    private String iouid;

    public IO_Point()
    {

    }

    public IO_Point(String type, String lan, String os, String ioNum, String label, String siteUID, Boolean actioned, String iouid)
    {
        this.type = type;
        this.lan = lan;
        this.os = os;
        this.ionum = ioNum;
        this.label = label;
        this.siteUID = siteUID;
        this.actioned = actioned;
        this.iouid = iouid;

    }

    public String getType()
    {
        return type;
    }

    public String getLan()
    {
        return lan;
    }

    public String getOS()
    {
        return os;
    }

    public String getIONum()
    {
        return ionum;
    }

    public String getLabel()
    {
        return label;
    }

    public String getSiteUID()
    {
        return siteUID;
    }

    public Boolean getActioned()
    {
        return actioned;
    }

    public String getIOUID()
    {
        return iouid;
    }

}

Database Sample

    {
  "IO Points" : {
    "-L9fzerDpRXR72ilvRht" : {
      "actioned" : true,
      "ionum" : "S1",
      "iouid" : "-L9fzerDpRXR72ilvRht",
      "label" : "Sensor One",
      "lan" : "1",
      "os" : "11",
      "siteUID" : "-L9fz_QYz8KFQtByYOxN",
      "type" : "S"
    },
    "-L9fzij0Kyt1x3F_W7Ea" : {
      "actioned" : false,
      "ionum" : "I1",
      "iouid" : "-L9fzij0Kyt1x3F_W7Ea",
      "label" : "Digital One",
      "lan" : "1",
      "os" : "11",
      "siteUID" : "-L9fz_QYz8KFQtByYOxN",
      "type" : "D"
    },
    "-L9fzlCaDhagrIzIzTTI" : {
      "actioned" : false,
      "ionum" : "D1",
      "iouid" : "-L9fzlCaDhagrIzIzTTI",
      "label" : "Output One",
      "lan" : "1",
      "os" : "11",
      "siteUID" : "-L9fz_QYz8KFQtByYOxN",
      "type" : "O"
    },
    "-L9g-Ppg9noyYepYRLMq" : {
      "actioned" : false,
      "ionum" : "S1",
      "iouid" : "-L9g-Ppg9noyYepYRLMq",
      "label" : "Sensor Two",
      "lan" : "1",
      "os" : "11",
      "siteUID" : "-L9g-Hr-v8zgO08zWGTP",
      "type" : "S"
    },
    "-L9g-XOoOSlv15PKiC0e" : {
      "actioned" : false,
      "ionum" : "I1",
      "iouid" : "-L9g-XOoOSlv15PKiC0e",
      "label" : "Digital Two",
      "lan" : "1",
      "os" : "11",
      "siteUID" : "-L9g-Hr-v8zgO08zWGTP",
      "type" : "D"
    },
    "-L9g-k0poRsnDi5ZyHjP" : {
      "actioned" : false,
      "ionum" : "D1",
      "iouid" : "-L9g-k0poRsnDi5ZyHjP",
      "label" : "Output Two",
      "lan" : "1",
      "os" : "11",
      "siteUID" : "-L9g-Hr-v8zgO08zWGTP",
      "type" : "O"
    }
  },
  "Sites" : {
    "-L9fz_QYz8KFQtByYOxN" : {
      "inProgress" : true,
      "siteAddress" : "Site One Address",
      "siteName" : "Site One",
      "siteUID" : "-L9fz_QYz8KFQtByYOxN"
    },
    "-L9g-Hr-v8zgO08zWGTP" : {
      "inProgress" : false,
      "siteAddress" : "Site Two Address",
      "siteName" : "Site Two",
      "siteUID" : "-L9g-Hr-v8zgO08zWGTP"
    }
  }
}

"Attempt to invoke virtual method on a null object reference" means that this object, that you try to do something with it, is not initialized.Debug your program and you must find where you "loose" this . Check the object in "LayoutInflater.java:233"!!

You have remove Firebase custom Child key and use Default

DatabaseReference save = FirebaseDatabase.getInstance().getReference("users");
String uid = save.push().getKey();
save.child(uid).setValue(new user(uid,"Milan"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM