【问题标题】:Geocoding client not sending requests to geocoding api地理编码客户端未向地理编码 api 发送请求
【发布时间】:2020-06-07 12:40:19
【问题描述】:

我正在尝试在 Firebase Cloud Function 上使用来自 Node.js 的 google-maps-services javascript library。我希望从街道地址获取 (lat, lng)。出于测试目的,我正在运行一个可调度的 firebase 函数并从那里调用库函数。但是,只有我的错误路径正在执行。下面是我正在使用的环境细节和代码sn-p

环境详情

  • 平台:Node.js v8 上的 firebase 云函数
  • 地理编码 API 版本:2.0.2

重现步骤

运行从地理编码 api 请求 (lat, lng) 的异步函数。函数体(index.js 内部)如下

async function getDriverLocationNearAddress(streetAddress){
const geocodingClient = new Client({});
let params = {
        address: streetAddress,
        components: 'country:US',
        key: API_KEY_GEOCODING
    }; 
    console.log('retrieving lat, lng for ' + streetAddress);
    return geocodingClient.geocode(params)
    .then((response)=>{
        console.log('status: ' + response.data.status);
        console.log(response.data.results[0].geometry.location.lat);
        console.log(response.data.results[0].geometry.location.lng);
        return response;
    })
    .catch((error)=>{
        console.log('error retrieving geocoded results');
    });
}

下面的初始化已经完成

API_KEY_GEOCODING='*******************************'; // key not shown
const Client = require("@googlemaps/google-maps-services-js").Client;

我每隔 1 分钟使用调度程序 API 定期运行此函数

exports.scheduledUpdateDriverLocations = functions.pubsub.schedule('every 1 minutes').onRun( (context) => {
    return getDriverLocationNearAddress('1042 Middlefield Rd, Redwood City, CA');
});

控制台日志显示我的getDriverLocationsNearAddress 一直在点击catch 语句,而没有在then 部分打印任何日志。

enter image description here

但是,如果我尝试使用浏览器访问地理编码 API,它可以正常工作 我的 google cloud api 控制台显示我没有收到任何 api 请求,除了使用浏览器发送的请求。在下图中,我只看到一个请求,尽管我每分钟发送一次请求,在指定事件后几分钟。

enter image description here

这是错误日志。看来我的请求格式不正确,但不知道为什么会这样

{ Error: Request failed with status code 400
    at createError (/srv/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/srv/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/srv/node_modules/axios/lib/adapters/http.js:236:11)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:139:11)
    at process._tickDomainCallback (internal/process/next_tick.js:219:9)
  config: 
   { url: 'https://maps.googleapis.com/maps/api/geocode/json',
     method: 'get',
     headers: 
      { Accept: 'application/json, text/plain, */*',
        'User-Agent': 'google-maps-services-node-2.0.2' },
     transformRequest: [ [Function: transformRequest] ],
     transformResponse: [ [Function: transformResponse] ],
     paramsSerializer: [Function],
     timeout: 10000,
     adapter: [Function: httpAdapter],
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: -1,
     validateStatus: [Function: validateStatus],
     httpsAgent: 
      HttpsAgent {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        defaultPort: 443,
        protocol: 'https:',
        options: [Object],
        requests: {},
        sockets: {},
        freeSockets: [Object],
        keepAliveMsecs: 1000,
        keepAlive: true,
        maxSockets: Infinity,
        maxFreeSockets: 256,
        createSocketCount: 52,
        createSocketCountLastCheck: 0,
        createSocketErrorCount: 0,
        createSocketErrorCountLastCheck: 0,
        closeSocketCount: 51,
        closeSocketCountLastCheck: 0,
        errorSocketCount: 0,
        errorSocketCountLastCheck: 0,
        requestCount: 52,
        requestCountLastCheck: 0,
        timeoutSocketCount: 51,
        timeoutSocketCountLastCheck: 0,
        maxCachedSessions: 100,
        _sessionCache: [Object],
        [Symbol(agentkeepalive#currentId)]: 52 },
     address: '1044 Middlefield Rd, Redwood City, CA',
     components: 'country:US',
     key: '************************************',
     data: undefined },
  request: 
   ClientRequest {
     domain: 
      Domain {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        members: [Array] },
     _events: 
      { socket: [Function],
        abort: [Function],
        aborted: [Function],
        error: [Function],
        timeout: [Array],
        prefinish: [Function: requestOnPrefinish] },
     _eventsCount: 6,
     _maxListeners: undefined,
     output: [],
     outputEncodings: [],
     outputCallbacks: [],
     outputSize: 0,
     writable: true,
     _last: true,
     upgrading: false,
     chunkedEncoding: false,
     shouldKeepAlive: true,
     useChunkedEncodingByDefault: false,
     sendDate: false,
     _removedConnection: false,
     _removedContLen: false,
     _removedTE: false,
     _contentLength: 0,
     _hasBody: true,
     _trailer: '',
     finished: true,
     _headerSent: true,
     socket: 
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'maps.googleapis.com',
        npnProtocol: false,
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 9,
        connecting: false,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: 'maps.googleapis.com',
        _readableState: [Object],
        readable: true,
        domain: [Object],
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: false,
        _bytesDispatched: 178,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [Object],
        _requestCert: true,
        _rejectUnauthorized: true,
        _idleTimeout: 15000,
        _idleNext: [Object],
        _idlePrev: [Object],
        _idleStart: 3119505,
        _destroyed: false,
        parser: null,
        _httpMessage: null,
        [Symbol(asyncId)]: -1,
        [Symbol(bytesRead)]: 0,
        [Symbol(asyncId)]: 4567,
        [Symbol(triggerAsyncId)]: 0,
        [Symbol(agentkeepalive#socketName)]: 'sock[51#maps.googleapis.com:443:::::::::]',
        [Symbol(agentkeepalive#socketRequestCount)]: 1,
        [Symbol(agentkeepalive#socketRequestFinishedCount)]: 1 },
     connection: 
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 

【问题讨论】:

  • 您的密钥是否受到限制?我怀疑客户端请求正在使用 Web 服务,在这种情况下,受限于 Javascript API 的密钥将不起作用。尝试创建一个 Web 服务密钥并使用它。
  • (或无限制键,用于快速测试)
  • 我按照您的建议尝试并将密钥设置为不受限制 - 删除了应用程序和 API 限制。仍然得到相同的结果。

标签: javascript firebase google-maps nodes geocoding


【解决方案1】:

可能,我看到的是您无法从您的网络服务器调用 API(跨源请求)。找到您的网络服务器名称(例如 localhost:8080)并将其添加为授权的 javascript 来源。有关必须遵循的确切步骤的信息,您可以找到here

当您可以使用浏览器访问但无法从 (javascript) 代码中访问 API 时,通常会出现这种情况。我还建议打印确切的错误而不是日志语句,或者只从您的 catch 块中打印两者。像这样的:

.catch((error)=>{
    console.log('Error retrieving geocoded results: ' + error);
});

【讨论】:

    【解决方案2】:

    google-map-services library for node.js 运行关于海拔API 的最小示例后,我发现问题与如何为geocode 函数提供参数有关。

    我将node.js代码改成如下

    之前:我没有提供字段名称params

    async function getDriverLocationNearAddress(streetAddress){
    const geocodingClient = new Client({});
    let params = {
            address: streetAddress,
            components: 'country:US',
            key: API_KEY_GEOCODING
        }; 
        console.log('retrieving lat, lng for ' + streetAddress);
        return geocodingClient.geocode(params)
        .then((response)=>{
            console.log('status: ' + response.data.status);
            console.log(response.data.results[0].geometry.location.lat);
            console.log(response.data.results[0].geometry.location.lng);
            return response;
        })
        .catch((error)=>{
            console.log('error retrieving geocoded results');
        });
    }
    

    之后:

    async function getDriverLocationNearAddress(streetAddress){
    const geocodingClient = new Client({});
    let params = {
            address: streetAddress,
            components: 'country:US',
            key: API_KEY_GEOCODING
        }; 
    
        console.log('retrieving lat, lng for ' + streetAddress);
        geocodingClient.geocode({
            params:params
        })
        .then((response)=>{
            console.log('status: ' + response.data.status);
            console.log(response.data.results[0].geometry.location.lat);
            console.log(response.data.results[0].geometry.location.lng);
            return response;
        })
        .catch((error)=>{
            console.log('error retrieving geocoded results');
        });
    }
    

    【讨论】:

    • 顺便说一句,我正在使用不受限制的 api 密钥运行
    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多