【问题标题】:Code afterwards getting executed first in Firebase cloud function之后的代码首先在 Firebase 云函数中执行
【发布时间】:2018-12-16 08:14:22
【问题描述】:

这是我的代码

 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");
});

我正在 Firebase 云中部署上述功能。我已经评论了哪些代码首先执行,哪些代码随后执行。我不明白为什么会这样。 之后执行的部分是从 firebase 获取数据并使用函数 getDistance 计算两点之间的距离。因为它在它下面的代码之前,所以应该先执行。

【问题讨论】:

    标签: javascript node.js firebase-realtime-database google-cloud-functions


    【解决方案1】:

    Firebase 使用 Promise,结果要么被解决,要么被拒绝。 这意味着结果(在您的情况下是获取的数据)需要一些时间。由于您的代码没有嵌套,因此任何其他函数都是异步执行的 我建议将您需要执行的内容嵌套在.then{} 块中,或者将功能解耦并将其放在单独的函数中,然后在传递相关参数(在本例中为快照数据)时调用该函数

    【讨论】:

      【解决方案2】:

      调用ref.on("value", callback) 将首先执行。不过,callback 将在未来某处执行。

      在您的情况下,您可能最好使用once

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

      所有其他逻辑都应该存在于then 中,因为它取决于snapshot 中的值:

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

      【讨论】:

      • 我使用了您的建议,但它给了我以下两个错误:(1)预期的 catch() 或返回。 (2) 每个 then() 都应该返回一个值或抛出。
      • 我能够解决上述错误,但同样的事情又发生了。
      • @GurjeetSingh 请更新您的问题以反映新情况。
      • 我已经用新代码更新了这个问题。即使更改了代码,我也面临同样的问题。
      • 您应该 return ref.once(... 并将您的所有逻辑移动到 then 内(见答案)
      猜你喜欢
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 2016-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      相关资源
      最近更新 更多