1

I try to create/update alarm data in firebase realtime database.

If there is an exinting alarm data for current user I want to update it.

I have a setClock method and try to control if there is an existing data so I write a new method(findAlarm) but I got a null object reference error.

I used Log.e to control that it is null or not but it is looking full.

I don't understand what is my fault. please help

public  void setClock( int hour,  int minute){
        Alarm alm=findAlarm();
        if(alm==null){
            String pushkey= databaseReference.push().getKey();
            Log.e("push",pushkey);
            Alarm alarm = new Alarm(hour,minute,firebaseUser.getUid(),pushkey);
            databaseReference.child(pushkey).setValue(alarm);
        }
        else{
            alm.setHour(hour);
            alm.setMin(minute);
            databaseReference.child(alm.getPushKey()).setValue(alm);
        }





    }
    public Alarm findAlarm(){
        final Alarm alarm2 = null;

        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {


                for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                    Log.e("hour", String.valueOf(postSnapshot.child("hour").getValue(int.class)));
                    Log.e("userid",postSnapshot.child("user").getValue(String.class));
                    Log.e("userid2",firebaseUser.getUid());


                    if(postSnapshot.child("user").getValue(String.class).equals(firebaseUser.getUid())) {
                        alarm2.setHour(postSnapshot.child("hour").getValue(int.class));
                        alarm2.setMin(postSnapshot.child("min").getValue(int.class));
                        alarm2.setPushKey(postSnapshot.child("pushKey").getValue(String.class));
                        alarm2.setUser(postSnapshot.child("user").getValue(String.class));
                    }
                }



            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        return alarm2;
    }

Logcat

E/hour: 23
E/userid: E3CFesWWcrM7WAJCPwDENbQCk2i2
E/userid2: E3CFesWWcrM7WAJCPwDENbQCk2i2
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.sozluk, PID: 7185
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.sozluk.Alarm.setHour(int)' on a null object reference
        at com.example.sozluk.Scroll$2.onDataChange(Scroll.java:111)
asdfg
  • 27
  • 6

1 Answers1

0

alarm2 is initially null, because you set it that way:

final Alarm alarm2 = null;

And you never gave it a new value, so it stays null as this line executes, crashing your app:

alarm2.setHour(postSnapshot.child("hour").getValue(int.class));

You will need to give it a value before calling methods on it. Unforutunately, you can't because you made it final so that you can use it inside the database callback.

In order to work with Firebase correctly, you will need to learn how to work with its APIs asynchronously, as they are designed. Queries don't return immediately. Your listener is going to get called some time later, after the query completes. You can only use the data from the snapshot in the listener.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 1
    For more on that last paragraph, I recommend reading https://stackoverflow.com/questions/50434836/getcontactsfromfirebase-method-return-an-empty-list/50435519#50435519, which contains some handy examples :) – Frank van Puffelen Apr 10 '20 at 23:45