Reputation: 687
Here is my code
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendMessage = functions.database.ref('/UserRequests/{uid}')
.onCreate((snap, context) => {
const position = snap.val();
var loc = [position.l[0], position.l[1]];
const db = admin.database();
const ref = db.ref('/DriversAvailable');
const drivers = new GeoFire(ref);
var data = [];
const pathId = context.auth.uid;
const ref1 = db.ref('/UserRequests/{pathId}');
console.log("UserID" + pathId);
ref.once('value').then(snapshot => {
snapshot.forEach(function (child) {
console.log(child.key + " key"); //This code gets executed afterwards.
var c = child.val();
var aaa = child.key;
var lat = c.l[0];
var lng = c.l[1];
var dist = getDistance(position.l[0], position.l[1], lat, lng);
console.log("dis" + lat + lng + "aaa" + dist);
data.push({
id: aaa,
dis: dist
});
});
return console.log("gotit");
});
var getDistance = function (lat1, lng1, lat2, lng2) {
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(lat2 - lat1);
var dLong = rad(lng2 - lng1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(rad(lat1)) * Math.cos(rad(lat2)) *
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d; // returns the distance in meter
};
var rad = function (x) {
return x * Math.PI / 180;
};
data.sort(function (a, b) {
return a.dis - b.dis
});
var i = 0;
var n = data.length;
console.log("number" + n); //This code is executed first.
while (i < 2 && i <= n) {
i++;
var k = data[i].id;
const getdevicetokenpromise = db.ref(`/DriversAvailable/${k}/token`).once('value');
return getdevicetokenpromise.then(result => {
console.log(result.val());
var token = result.val();
const payload = {
data: {
uid: pathId
}
};
return admin.messaging().sendToDevice(token, payload)
.then((response) => {
return console.log("Successfully sent message:", response);
})
.catch((error) => {
console.log("Error sending message:", error);
});
});
}
console.log("hi");
});
I am deploying the above function in Firebase cloud. I have commented about which code is being executed first and which is executed afterwards. I couldn't get why this is happening. The part which is executed afterwards is taking data from firebase and computing the distance between two points using the function getDistance. As it comes before the code below it, it should be executed first.
Upvotes: 2
Views: 184
Reputation: 1729
Firebase works with promises, whereby the result is either resolved or rejected.
that means that the result, in your case the data fetched, takes sometime. Since your code is not nested, any other functions are executed asyncronously
I suggest nesting what you need executed within the .then{}
block, or decoupling the functionality and putting it in a separate function, then calling that function while passing relevant parameters, in this case the snapshot data
Upvotes: 2
Reputation: 11244
The call ref.on("value", callback)
will be executed first. The callback
however will be executed somewhere in the future.
In you case you are probably better of using once
:
ref.once('value').then(snapshot => ...)
All other logic should live inside the then
as it depends on the value in the snapshot
:
return ref.once('value).then(snapshot => {
var data = []
...
snapshot.forEach(child => {
data.push(...)
})
...
// other code
})
Upvotes: 1