如何使用NodeJS中的firebase云功能从firebase实时数据库中找出最近的位置LatLng

Posted

技术标签:

【中文标题】如何使用NodeJS中的firebase云功能从firebase实时数据库中找出最近的位置LatLng【英文标题】:How to find out nearest location LatLng from firebase real-time database using firebase cloud function in NodeJS 【发布时间】:2019-06-16 05:21:07 【问题描述】:

数据库:

大家好, 我正在尝试使用云功能从 1 公里半径内的 firebase 实时数据库中搜索 LatLng。但是在日志中显示的自爆之后,我遇到了一个问题。

问题:

未配置结算帐户。外部网络无法访问 并且配额受到严格限制。配置结算帐号以删除 这些限制 函数执行耗时 60002 毫秒,完成 状态:“超时”

源代码:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

//https://*********.cloudfunctions.net/searchNearbyLatLng?originlat=23.7939419&originlng=90.3888492
exports.searchNearbyLatLng = functions.https.onRequest((request, response) => 

  let lat1Param = request.query.originlat;
  let lng1Param = request.query.originlng;

  let rootRef = admin.database().ref('riders_online');
  rootRef.once('value', gotData, errData);


  function gotData(data) 
    let items = data.val();
    let keys = Object.keys(items);
    for (let i = 0; i < keys.length; i++) 
      let key = keys[i];
      let item = items[key];
      //console.log(item.isUserRequested, item.riderOriginLatitude, key);
      let distance = getDistance( lat1Param, lng1Param, data.val().riderOriginLatitude, data.val().riderOriginLongitude );
      if( distance < 1 ) 
        response.send('Record' + item.riderOriginLatitude);
      
    
  

  function errData(error) 
    console.log("Something went wrong.");
    console.log(error);
  

  function getDistance( latitude1, longitude1, latitude2, longitude2 ) 
    let earth_radius = 6371;
    let dLat = degToRad( latitude2 - latitude1 );
    let dLng = degToRad( longitude2 - longitude1 );
    let a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(degToRad(latitude1)) * Math.cos(degToRad(latitude2)) * Math.sin(dLng/2) * Math.sin(dLng/2);
    let c = 2 * Math.asin(Math.sqrt(a));
    let d = earth_radius * c;
    return d;
  
  function degToRad(degrees)
    let pi = Math.PI;
    return degrees * (pi/180);
  

, err => 
    console.error(err.stack);
    response.status(500).send('Unexpected error.');
);

【问题讨论】:

【参考方案1】:

由于 Firebase 不支持地理空间查询,我建议使用 geohash

这在这个 firebase 博客上得到了很好的展示:

https://firebase.googleblog.com/2013/09/geofire-location-queries-for-fun-and.html

【讨论】:

感谢剪切知识。但是我已经解决了这个问题并分享了代码 该库在其 repo 中有详细记录:github.com/firebase/geofire-js 更具体的例子位于github.com/firebase/geofire-js/tree/master/examples 是的,兄弟,GeoFire 运行良好。但是我需要解决我的云功能代码。我已经完成并开始工作了...:) 谢谢兄弟。【参考方案2】:

const functions = require('firebase-functions');
//const GeoFire = require('geofire');

const admin = require('firebase-admin');
admin.initializeApp();

exports.searchNearbyLatLng = functions.runWith( memory: '1GB', timeoutSeconds: 120 ).https.onRequest((request, response) => 

  let lat1Param = request.query.originlat;
  let lng1Param = request.query.originlng;
  let lat2Param = request.query.destLat;
  let lng2Param = request.query.destLng;

  let rootRef = admin.database().ref('riders_online').orderByChild('isUserRequested').equalTo('false');
  rootRef.once('value', gotData, errData);

  // The data comes back as an object
  function gotData(data) 
    let items = data.val();
    // Grab all the keys to iterate over the object
    let keys = Object.keys(items);
    // Loop through array
    for (let i = 0; i < keys.length; i++) 
      let key = keys[i];
      let item = items[key];
      console.log(item.isUserRequested, item.riderOriginLatitude, key);
      //response.json(data.val());

      let distance = getDistance( lat1Param, lng1Param, item.riderOriginLatitude, item.riderOriginLongitude );
      if( distance < 1 ) 
        let dist = getDistance( lat2Param, lng2Param, item.riderDestinationLatitude, item.riderDestinationLongitude );
        if( dist < 1 ) 
          let jsonData = 
            "info": 
              "createdAt": item.info.createdAt,
              "riderBirthDate": item.info.riderBirthDate,
              "riderDistrict": item.info.riderDistrict,
              "riderEmail": item.info.riderEmail,
              "riderFullName": item.info.riderFullName,
              "riderGender": item.info.riderGender,
              "riderImageUrl": item.info.riderImageUrl,
              "riderLicense": item.info.riderLicense,
              "riderNid": item.info.riderNid,
              "riderPhoneNumber": item.info.riderPhoneNumber,
              "riderToken": item.info.riderToken,
              "riderVehicle": item.info.riderVehicle,
              "riderVehicleNo": item.info.riderVehicleNo
            ,
            "isUserRequested": item.isUserRequested,
            "riderAvailableTime": item.riderAvailableTime,
            "riderDestinationLatitude": item.riderDestinationLatitude,
            "riderDestinationLongitude": item.riderDestinationLongitude,
            "riderOriginLatitude": item.riderOriginLatitude,
            "riderOriginLongitude": item.riderOriginLongitude,
            "riderPrice": item.riderPrice,
            "riderToken": item.riderToken
          
          response.json(jsonData);
        
      
    

  

  function errData(error) 
    console.log("Something went wrong.");
    console.log(error);
  

  function getDistance( latitude1, longitude1, latitude2, longitude2 ) 
    let earth_radius = 6371;
    let dLat = degToRad( latitude2 - latitude1 );
    let dLng = degToRad( longitude2 - longitude1 );
    let a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(degToRad(latitude1)) * Math.cos(degToRad(latitude2)) * Math.sin(dLng/2) * Math.sin(dLng/2);
    let c = 2 * Math.asin(Math.sqrt(a));
    let d = earth_radius * c;
    return d;
  

  function degToRad(degrees)
    let pi = Math.PI;
    return degrees * (pi/180);
  

, err => 
    console.error(err.stack);
    response.status(500).send('Unexpected error.');
);

【讨论】:

以上是关于如何使用NodeJS中的firebase云功能从firebase实时数据库中找出最近的位置LatLng的主要内容,如果未能解决你的问题,请参考以下文章

使用 NodeJs 服务器中的 firebase 云消息在特定时间和日期安排通知

如何使用 Firebase 实现忘记密码功能?

如何从 firebase 云功能访问 bigquery 数据?

使用 Firebase 云功能和 Firestore 在 android 上验证购买 [关闭]

如何从 Firebase Cloud 功能中提取已部署的云功能 [重复]

如何在云功能中的两个 Firebase 项目之间切换? [复制]