简体   繁体   中英

Returning a value from callback function

I am using the on() method to retrieve a data snapshot in our database, but I need to be able to store this snapshot value so that I can use it to retrieve another separate snapshot.

Here is what our database looks like: Firebase Real-Time Database

There is a node for users and a separate node for devices. Each user has a child "devices" which is a list of devices associated with that user. The user that I have expanded only has one device.

What I am trying to do is store this deviceID, and then do a separate query to find that device in the "Devices" node. Here is what my code looks like:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.on("value", getData);

And then the callback function looks like this:

function getData(data)
{ 
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
}

which is just grabbing the first device in the users device list and printing it to the console. I am trying to figure out how to return this value so that I can use it when getting the data from the Devices tree. Which, I'm guessing, would look something like this:

let deviceRef = database.ref("devices/").child(retrievedValue);
deviceRef.on("value", getData2);

Where retrievedValue is the deviceID that I got from the first query.

Is it possible to do this in javascript, or is there a better way? I know similar questions have already been asked, but I've found all the examples I've seen online to be really confusing and not very helpful for me. Any help at all would be super appreciated because I am kind of stuck on this. Thanks!

In order to achieve that, you have to modify your callback as following:

function getData(data, callback)
{ 
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
  callback(currentDevice)
}

Then we you call your callback from within the code, do it like this:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.on("value", getData((this_is_the_value_from_inside_callback) => {
  console.log(`your value: ${this_is_the_value_from_inside_callback}`)
});

You can also try to run this little snippet (I used PlayCode), to see it more friendly testing environment

somefunction = (data, callback) => {

  console.log(`data: ${data}`)
  data += 100
  console.log(`data: ${data}`)
  callback(data)
}

somefunction(100, (dataReturned) => {
  console.log(`data returned: ${dataReturned}`)
})

You have to learn about promises and asynchronous programming. Here are two ways to do what you want:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.once("value").then((data) {
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
  let deviceRef = database.ref("devices/").child(currentDevice);
  return deviceRef.once("value");
}).then((value) {
  console.log("value is " + value);
})

or with async/await:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
let data = await ref.once("value")
currentDevice = Object.keys(data.val())[0];
console.log("current device: " + currentDevice); 
let deviceRef = database.ref("devices/").child(currentDevice);
let value = await deviceRef.once("value");
console.log("value is " + value);

I'm more confident about the second one as I'm typing these without testing.

These links would be helpful to start learning this stuff: https://firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html https://firebase.google.com/docs/functions/terminate-functions

Edit: I fixed the code above by replacing on with once . However now this is not listening to changes in the db anymore. To correct your code to listen to user's device changes:

let uid = fireBaseUser.uid; 
//get a reference to the database
let database = firebase.database();
let ref = database.ref("users/").child(uid).child("devices"); 
ref.on("value", getData);

function getData(data) // may need to place this before the code above
{ 
  currentDevice = Object.keys(data.val())[0];
  console.log("current device: " + currentDevice); 
  let deviceRef = database.ref("devices/").child(currentDevice);

  // no need to listen to this, as a change in one device would fire 
  // for every user. you probably don't want that. 
  deviceRef.once("value", (data) { 
    console.log(data);
  });
}

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