简体   繁体   English

之后首先在Firebase云功能中执行代码

[英]Code afterwards getting executed first in Firebase cloud function

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. 我正在Firebase云中部署上述功能。 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. 之后执行的部分是从firebase中获取数据并使用getDistance函数计算两点之间的距离。 As it comes before the code below it, it should be executed first. 由于它位于其下面的代码之前,因此应首先执行。

Firebase works with promises, whereby the result is either resolved or rejected. Firebase与promise一起工作,从而解决结果或拒绝结果。 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 由于您的代码未嵌套,因此建议您在.then{}块中嵌套您需要执行的内容,或者将功能解耦并将其放在单独的函数中,然后在传递相关参数的同时调用该函数,这种情况下快照数据

The call ref.on("value", callback) will be executed first. 调用ref.on("value", callback)将首先执行。 The callback however will be executed somewhere in the future. 但是, callback将在将来的某个地方执行。

In you case you are probably better of using once : 在这种情况下,最好使用once

ref.once('value').then(snapshot => ...)

All other logic should live inside the then as it depends on the value in the snapshot : 所有其他逻辑都应驻留在then因为它取决于snapshot的值:

return ref.once('value).then(snapshot => {
  var data = []
  ...
  snapshot.forEach(child => {
    data.push(...)
  })
  ...
  // other code
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM