Javascript 在Firebase cloud函数中首先执行代码
这是我的密码Javascript 在Firebase cloud函数中首先执行代码,javascript,node.js,firebase-realtime-database,google-cloud-functions,Javascript,Node.js,Firebase Realtime Database,Google Cloud Functions,这是我的密码 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 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");
});
const functions=require('firebase-functions');
const admin=require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendMessage=functions.database.ref(“/UserRequests/{uid}”)
.onCreate((快照,上下文)=>{
常量位置=snap.val();
var loc=[position.l[0],position.l[1];
const db=admin.database();
const ref=db.ref('/DriversAvailable');
常量驱动程序=新的GeoFire(参考);
var数据=[];
const pathId=context.auth.uid;
const ref1=db.ref('/UserRequests/{pathId}');
console.log(“UserID”+pathId);
参考一次(“值”)。然后(快照=>{
snapshot.forEach(函数(子函数){
console.log(child.key+“key”);//此代码随后执行。
var c=child.val();
var aaa=child.key;
var lat=c.l[0];
var lng=c.l[1];
var dist=getDistance(位置l[0],位置l[1],纬度,液化天然气);
控制台日志(“dis”+lat+lng+“aaa”+dist);
数据推送({
id:aaa,
dis:区
});
});
返回console.log(“gotit”);
});
var getDistance=函数(lat1、lng1、lat2、lng2){
var R=6378137;//以米为单位的地球平均半径
var dLat=拉德(lat2-lat1);
var dLong=rad(lng2-lng1);
变量a=Math.sin(dLat/2)*Math.sin(dLat/2)+
数学cos(rad(lat1))*数学cos(rad(lat2))*
数学单(长/2)*数学单(长/2);
var c=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
var d=R*c;
return d;//返回以米为单位的距离
};
var rad=函数(x){
返回x*Math.PI/180;
};
数据排序(函数(a,b){
返回a.dis-b.dis
});
var i=0;
var n=数据长度;
console.log(“number”+n);//首先执行此代码。
而(i<2&&i){
console.log(result.val());
var token=result.val();
常数有效载荷={
数据:{
uid:pathId
}
};
返回admin.messaging().sendToDevice(令牌、负载)
。然后((响应)=>{
返回console.log(“成功发送消息:”,响应);
})
.catch((错误)=>{
日志(“发送消息时出错:”,错误);
});
});
}
控制台日志(“hi”);
});
我正在Firebase云中部署上述功能。我已经评论了哪些代码是先执行的,哪些是后执行的。我不明白为什么会这样。
随后执行的部分是从firebase获取数据,并使用函数getDistance计算两点之间的距离。由于它位于它下面的代码之前,所以应该首先执行。调用ref.on(“value”,callback)
将首先执行。但是,回调
将在将来的某个地方执行
在您的情况下,最好只使用一次:
ref.once('value').then(snapshot => ...)
所有其他逻辑都应该在中,然后在中,因为它取决于快照中的值:
return ref.once('value).then(snapshot => {
var data = []
...
snapshot.forEach(child => {
data.push(...)
})
...
// other code
})
Firebase与承诺一起工作,结果要么被解决,要么被拒绝。
这意味着在您的情况下,获取数据的结果需要一些时间。因为您的代码不是嵌套的,所以任何其他函数都是异步执行的
我建议将需要执行的内容嵌套在.then{}
块中,或者将功能解耦并将其放入一个单独的函数中,然后在传递相关参数时调用该函数,在本例中,快照数据使用了您的建议,但它给了我以下两个错误:(1)预期的catch()或return。(2) 每个then()都应返回一个值或抛出。我能够解决上述错误,但同样的情况再次发生。@GurjeetSingh请更新您的问题以反映新情况。我已使用新代码更新了问题。即使在更改代码后,我也面临同样的问题。您应该返回ref.one(…
并将所有逻辑移到中,然后
(参见答案)