Home > Software design >  How to compare two children of Firebase Realtime Database?
How to compare two children of Firebase Realtime Database?

Time:02-09

Based on the result of data.key === "high_temp_coil", I am printing the data into my webpage with data.val() as shown below:

var deviceRef = app.database().ref('/' localStorage.getItem('machineid'));
deviceRef.on('child_added', function(data) {
  if (data.key === 'high_temp_coil') {
    $('#high_temp_coil .value').html(data.val())
  }
  if (data.key === 'low_temp_coil') {
    $('#low_temp_coil .value').html(data.val());
  }
}

In my code high_temp_coil represents the high temperature of the coil and low_temp_coil represents the low temperature of the coil, each with their own fields in my database. However, due to a manufacturing issue, sometimes the high temp and low temps are backwards and I need to figure this out before printing the data. This is how I was trying to do that but it doesn't work:

if (data.key === "high_temp_coil"){
  let valueh= data.val(); 
  if (data.key === "low_temp_coil"){
    let valuel= data.val()
    console.log(valueh);
    console.log(valuel);
  }
}

This is what the data looks like in my database:

{
  "MachineNo": {
    "water": "value"
    "high_temp_coil": "value"
    "low_temp_coil": "value"
  }
}

CodePudding user response:

When you use a child_added event listener, your callback will be invoked whenever one of the children under that database location changes. Using this, you would need to store high_temp_coil and low_temp_coil in variables outside of the function so that you can compare them properly. Because you store the result in an element, you could pull the current values from there.

Note: In the below snippets I follow the convention of naming the DataSnapshot object as snapshot, reserving data for the plain JavaScript object returned by snapshot.val(). This aids in preventing confusion later on, especially when not using TypeScript.

var deviceRef = app.database().ref('/' localStorage.getItem('machineid'));
deviceRef.on('child_added', function(snapshot) {
  if (snapshot.key === 'high_temp_coil') {
    const newHighTempValue = snapshot.val();
    const lowTempValue = $('#low_temp_coil .value').html();
    if (Number(newHighTempValue) >= Number(lowTempValue)) { // <- assuming the values are numeric and not written as "52.1°C"
      // new value is higher than current value
      $('#high_temp_coil .value').html(newHighTempValue)
    } else {
      // new value is lower than current value, swap places
      $('#high_temp_coil .value').html(lowTempValue)
      $('#low_temp_coil .value').html(newHighTempValue)
    }
  }
  if (snapshot.key === 'low_temp_coil') {
    const newLowTempValue = snapshot.val();
    const highTempValue = $('#high_temp_coil .value').html();
    if (Number(newLowTempValue) < Number(highTempValue)) { // <- assuming the values are numeric and not written as "52.1°C"
      // new value is lower than current value
      $('#low_temp_coil .value').html(newLowTempValue)
    } else {
      // new value is higher than current value, swap places
      $('#low_temp_coil .value').html(highTempValue)
      $('#high_temp_coil .value').html(newLowTempValue)
    }
  }
}

The main issue with the above code is that the child_added events would fire once on page load, and not get live updates from any sensors updating the data because these changes would fire child_changed events.

However, for your data structure, you can greatly simplify your code by listening to value events instead. These listeners will be fired each time any of the data under that location is updated - including when a machine is created and any changes to the temperatures. Also, because the data is one level higher in the tree, you have access to the latest high_temp_coil and low_temp_coil values right in the snapshot. The trade-off for this listener is that you need to make sure to handle when the data does not exist (snapshot.exists()===false) because child_added listeners would only be invoked when data is created where it is guaranteed to exist.

var deviceRef = app.database().ref('/' localStorage.getItem('machineid'));
deviceRef.on(
  'value',
  function(snapshot) {
    if (!snapshot.exists()) {
      // TODO: handle machine does not exist
      console.error(`Machine ${localStorage.getItem('machineid')} does not exist in database`);
      return;
    }

    const data = snapshot.val();
    const highTempValue = data.high_temp_coil;
    const lowTempValue = data.low_temp_coil;

    if (Number(highTempValue) >= Number(lowTempValue)) { // <- assuming the values are numeric and not written as "52.1°C"
      $('#high_temp_coil .value').html(highTempValue)
      $('#low_temp_coil .value').html(lowTempValue)
    } else {
      $('#high_temp_coil .value').html(lowTempValue)
      $('#low_temp_coil .value').html(highTempValue)
    }
  },
  (error) => {
    // TODO: implement better error handling
    console.error("Listener was cancelled due to an error:", error);
  }
);
  •  Tags:  
  • Related