【问题标题】:Invalid location: latitude must be a number位置无效:纬度必须是数字
【发布时间】:2019-12-26 01:09:39
【问题描述】:

我正在尝试使用geofirestore 执行地理查询。我想抓取给定集合中 1000 半径内的所有文档。

这是我的 .js 文件:

const GeoFirestore = require('geofirestore').GeoFirestore;
const GeoPoint = require('geopoint');
const firebase = require('firebase');

firebase.initializeApp({
    projectId : 'my-project-id'
});

module.exports = {
   getLocalDocuments: getLocalDocuments
}

async function getLocalDocuments() {
    let latitude = 38.9537323;
    let longitude = -77.3507578;
    let radius = 1000;

    // Create a Firestore reference
    const firestore = firebase.firestore();

    // Create a GeoFirestore reference
    const geofirestore = new GeoFirestore(firestore);

    // Create a GeoCollection reference
    const geocollection = geofirestore.collection('myDocs');

    const query = geocollection.near({
        center: new GeoPoint(latitude, longitude),
        radius
    });

    // Get query (as Promise)

    await query.get().then((value) => {
        console.log(`value.docs: ${value.docs}`); // All docs returned by GeoQuery
    });
}

当调用 getLocalDocuments() 函数时,我得到以下堆栈跟踪:

Error: Invalid location: latitude must be a number
    at validateLocation (/srv/node_modules/geofirestore/dist/index.cjs.js:567:15)
    at validateQueryCriteria (/srv/node_modules/geofirestore/dist/index.cjs.js:600:9)
    at GeoCollectionReference.GeoQuery.near (/srv/node_modules/geofirestore/dist/index.cjs.js:1416:9)
    at getLocalDocuments (/srv/utils/locationService.js:45:33)
    at Object.getLocalDocuments (/srv/utils/locationService.js:58:11)
    at buildLocalTPRecipients (/srv/utils/notificationInstructorGenerator.js:370:43)
    at notifyTPOfLocalJobsInstructionGenerator (/srv/utils/notificationInstructorGenerator.js:255:32)
    at Object.generateNewJobInstructions (/srv/utils/notificationInstructorGenerator.js:98:29)
    at handleOnCreate (/srv/db/jobs/onCreate.f.js:20:53)
    at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23)

这里是 validateLocation 方法:

function validateLocation(location, flag) {
    if (flag === void 0) { flag = false; }
    var error;
    if (!location) {
        error = 'GeoPoint must exist';
    }
    else if (typeof location.latitude === 'undefined') {
        error = 'latitude must exist on GeoPoint';
    }
    else if (typeof location.longitude === 'undefined') {
        error = 'longitude must exist on GeoPoint';
    }
    else {
        var latitude = location.latitude;
        var longitude = location.longitude;
        if (typeof latitude !== 'number' || isNaN(latitude)) {
            error = 'latitude must be a number';
        }
        else if (latitude < -90 || latitude > 90) {
            error = 'latitude must be within the range [-90, 90]';
        }
        else if (typeof longitude !== 'number' || isNaN(longitude)) {
            error = 'longitude must be a number';
        }
        else if (longitude < -180 || longitude > 180) {
            error = 'longitude must be within the range [-180, 180]';
        }
    }
    if (typeof error !== 'undefined' && !flag) {
        throw new Error('Invalid location: ' + error);
    }
    else {
        return !error;
    }
}

知道为什么说纬度不是数字吗?我检查了 isNaN() 和其他方法,他们都说这是一个数字。

【问题讨论】:

  • console.log(typeof location.latitude); 说什么? (或经度)
  • 这里是 validateLocation 方法 - 你需要说明它是如何/在哪里被调用的
  • @mwilson 我无法将该语句添加到 validateLocation 方法,因为它是节点模块包的一部分。我在部署云功能时忽略了这个文件夹。
  • @JaromandaX 它正在通过 geocollection.near({...}) 调用内部传递的对象的 center 属性。希望这会有所帮助。
  • location.latitudelocation.longitude 持有什么值?您可能需要添加一些 console.log 语句来调试,因为有些东西似乎有点不对劲。至于GeoPoint,您可以使用getLatitude()getLongitude() 来检索某个GeoPoint 对象的值。请记住,GeoPoint(double latitude, double longitude) 是一个元组。

标签: javascript node.js firebase google-cloud-firestore geofirestore


【解决方案1】:

问题位于以下代码行的validateLocation 函数内部:

var latitude = location.latitude;
var longitude = location.longitude;

相反,这些行应该是:

var latitude = location.latitude();
var longitude = location.longitude();

因为latitudelongitude 是getter 方法。


GeoPoint GitHub 所述

.latitude(inRadians):返回点的纬度。默认情况下,纬度以度为单位,除非 inRadians 为 true

.longitude(inRadians):返回点的经度。默认情况下,经度以度为单位,除非 inRadians 为真


重现步骤

创建某个GeoPoint

var GeoPoint = require('geopoint'),
statueOfLiberty = new GeoPoint(40.689604, -74.04455);

然后,console.log(statueOfLiberty),这是预期的输出

GeoPoint {
  _degLat: 40.689604,
  _degLon: -74.04455,
  _radLat: 0.7101675611326549,
  _radLon: -1.2923211906575673 
}

之后,为了验证上面的GeoPoint,我使用了validateLocation(location, flag)函数,和你用过的一样,也可以是找到 here:

function validateLocation(location, flag){

    if (flag === void 0) { flag = false; }
    var error;
    if (!location) {
        error = 'GeoPoint must exist';
    }
    else if (typeof location.latitude === 'undefined') {
        error = 'latitude must exist on GeoPoint';
    }
    else if (typeof location.longitude === 'undefined') {
        error = 'longitude must exist on GeoPoint';
    }
    else {
        var latitude = location.latitude;
        var longitude = location.longitude;
        if (typeof latitude !== 'number' || isNaN(latitude)) {
            error = 'latitude must be a number';
        }
        else if (latitude < -90 || latitude > 90) {
            error = 'latitude must be within the range [-90, 90]';
        }
        else if (typeof longitude !== 'number' || isNaN(longitude)) {
            error = 'longitude must be a number';
        }
        else if (longitude < -180 || longitude > 180) {
            error = 'longitude must be within the range [-180, 180]';
        }
    }
    if (typeof error !== 'undefined' && !flag) {
        throw new Error('Invalid location: ' + error);
    }
    else {
        return !error;
    }
}

调用代码中的函数,如下所示:

validateLocation(statueOfLiberty);


结果与您收到的错误消息没有什么不同。

当您在上面提到的validateLocation 函数中使用正确的getter 方法调用 时,整个故事发生了变化:

var latitude = location.latitude();
var longitude = location.longitude();

【讨论】:

    【解决方案2】:

    所以,您不应该/不应该使用名为“geopoint”的库。 Geopoints 是一个 firebase/firestore 对象...

    const firebase = require('firebase');
    const GeoPoint = firebase.firestore.GeoPoint;
    

    做出改变,其他一切都应该工作。

    【讨论】:

      猜你喜欢
      • 2018-03-30
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多