首页 > 解决方案 > 之后的代码首先在 Firebase 云函数中执行

问题描述

这是我的代码

 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 计算两点之间的距离。因为它在它下面的代码之前,它应该首先被执行。

标签: javascriptnode.jsfirebase-realtime-databasegoogle-cloud-functions

解决方案


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


推荐阅读