0

I have the following structure in Firebase:

app-default-rtdb
-Rooms
      -1
         -nrCards: 5
         -pin: 10001
         -roomName: Test
      -2
         -nrCards: 9
         -pin:10002
         -roomName: Test2

When I click a button I want to locate the last record added and retrieve the value of the "pin" so in this case, it should be 10002. In Android Studio, I wrote the following code but my app crashes and the value can not be retrieved inside a parameter type int.

room_hc=new RoomSettingsHelperClass();   //the java class where I keep the attributes
ref= FirebaseDatabase.getInstance().getReference().child("Rooms");

 btn_next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ref.orderByChild("pin").limitToLast(1).addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        Log.i("MY INFO: ", String.valueOf(snapshot.getValue()));
                        int pinNumber =Integer.parseInt((String) snapshot.child("pin").getValue());
                        room_hc.setPin(pinNumber);
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {
                        Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                    }
                });
});


When opening the messages executed it shows this:

I/MY INFO:: {2={pin=10002, nrCards=9, roomName=Test2}}
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.game.mygame, PID: 15440
    java.lang.NumberFormatException: s == null

Does anybody know how to fix it? I just want to retrieve the pin value inside an int parameter.

Stef
  • 13
  • 3
  • It seems that the problem is with the line `Integer.parseInt((String) snapshot.child("pin").getValue());` As if you're trying to parse a string that doesn't have an int. Try logging `snapshot.child("pin").getValue()` without parsing it and see what it gives – Salim Mahboubi Aug 02 '21 at 18:09
  • Does this answer your question? [What is a NumberFormatException and how can I fix it?](https://stackoverflow.com/questions/39849984/what-is-a-numberformatexception-and-how-can-i-fix-it) – Salim Mahboubi Aug 02 '21 at 18:09
  • It underlines the code with red and it is saying: Required: int; Provided: Object and it suggests to add an "(int)" before "snapshot" but now I get another error: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference – Stef Aug 02 '21 at 18:53

1 Answers1

1

When you are using the following method call:

ref.orderByChild("pin")

It means that the result you can get might contain a list with multiple objects. Even if you limit the query using a call to:

.limitToLast(1)

The result is still a list that contains a single object. This means that you have to loop through the results in order to get the value of "pin". So please try the code below:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference roomsRef = rootRef.child("Rooms");
Query queryLastRoom = roomsRef.orderByChild("pin").limitToLast(1);
queryLastRoom.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            for (DataSnapshot snapshot : task.getResult().getChildren()) {
                long pin = snapshot.child("pin").getValue(Long.class);
                Log.d("TAG", "pin: " + pin);
            }
        } else {
            Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
        }
    }
});

The result in the logcat will be:

pin: 10002
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Hey Alex. Your answer helped me indeed. I just changed a bit the query because it gave me an error plus I stored the value inside an int not a long, so instead of writing: "Query queryLastRoom = roomsRef.orderByChild("pin").limitToLast(1);" I wrote: "final Query queryLastRoom = ref.orderByKey().limitToLast(1);" so that I have the values for the last key entered in firebase which is 2 in this case. In this moment the value has been retrieved inside the int parameter "pin" – Stef Aug 08 '21 at 09:59