Springboot + ReactJS + Firebase's Realtime Database

Viewed 656

Back-end: Springboot Front-end: ReactJS CloudRepo: Firebase Realtime Database

  1. I have a Springboot application that GETs data from the Firebase Realtime Database.
  2. This data is then served via a GET request from reactJS.

I get the JSON object in reactJS as :

enter image description here

What I am trying to do is to map the firebase snapshot to a Java Collection. Here is What I have done so far:

DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.addValueEventListener(new ValueEventListener() {
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
            DeviceData message = messageSnapshot.getValue(DeviceData.class);
            System.out.println(message);
        }

        Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
        setUpdatedDocumentData(document);
    }

    public void onCancelled(DatabaseError error) {
        System.out.print("-----Error-----:\n" + error.getMessage());
    }
});

My POJO looks like this:

public class DeviceData {
    String sensor_1;
    String sensor_2;

    public DeviceData() {}

    public DeviceData(String sensor_1, String sensor_2) {
        this.sensor_1 = sensor_1;
        this.sensor_2 = sensor_2;
    }

    public String getSensor_1() {
        return sensor_1;
    }

    public void setSensor_1(String sensor_1) {
        this.sensor_1 = sensor_1;
    }

    public String getSensor_2() {
        return sensor_2;
    }

    public void setSensor_2(String sensor_2) {
        this.sensor_2 = sensor_2;
    }

    @Override
    public String toString() {
        return "DeviceData{" +
                "sensor_1='" + sensor_1 + '\'' +
                ", sensor_2='" + sensor_2 + '\'' +
                '}';
    }
}

I am getting null in my sensor_1 and sensor_2 log. How can I map the above firebase structure to a collection?

1 Answers

Under each /devices/$device node, you have two nested levels:

  1. For the date
  2. For the time.

Your code only has once loop over the children of the device node, so your messageSnapshot variable is actually a snapshot with all data for all timestamps for a specific date.

To handle your structure correctly, you need two nested loops:

DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.addValueEventListener(new ValueEventListener() {
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot dateSnapshot: dataSnapshot.getChildren()) {
            for (DataSnapshot timeSnapshot: dataSnapshot.getChildren()) {
                DeviceData message = timeSnapshot.getValue(DeviceData.class);
                System.out.println(message);
            }
        }

        Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
        setUpdatedDocumentData(document);
    }

    public void onCancelled(DatabaseError error) {
        System.out.print("-----Error-----:\n" + error.getMessage());
    }
});

If you only care about the latest timestamp on the latest date, you can reduce the amount of data you read from the database by only getting the latest date:

DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() {
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot dateSnapshot: dataSnapshot.getChildren()) {
            for (DataSnapshot timeSnapshot: dataSnapshot.getChildren()) {
                DeviceData message = timeSnapshot.getValue(DeviceData.class);
                System.out.println(message);
            }
        }

        Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
        setUpdatedDocumentData(document);
    }

    public void onCancelled(DatabaseError error) {
        System.out.print("-----Error-----:\n" + error.getMessage());
    }
});

You'll still have to read all timestamps for that date, but at least you're now only reading data for the most recent day.

Related