request(...)。那么在发出POST请求时不是函数错误

时间:2019-08-21 14:58:24

标签: javascript node.js request google-cloud-firestore google-cloud-functions

我正在尝试创建一个firebase函数,该函数在创建新文档时都会发出HTTP POST请求。

这是我的代码:

import * as functions from 'firebase-functions';

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

const request = require("request");


exports.sendMessage = functions.firestore.document('comms/{comms}').onCreate((snap, context) => {


  const newValue = snap.data();

  if (newValue) {

    //const email = newValue.email;
    const msg = newValue.msg;


    return request({
      uri: "url",
      method: 'POST',
      body: msg,
      json: true,
      resolveWithFullResponse: true
    }).then((response: { statusCode: number; }) => {
      if (response.statusCode >= 400) {
        throw new Error(`HTTP Error: ${response.statusCode}`);
      }
      console.log('SUCCESS! Posted', msg);
    });

  }

 return Promise 
});
Error received:

TypeError:request(...)。then不是一个函数     在exports.sendMessage.functions.firestore.document.onCreate(/srv/lib/index.js:25:12)     在cloudFunction(/srv/node_modules/firebase-functions/lib/cloud-functions.js:127:23)     在/worker/worker.js:825:24     在     在process._tickDomainCallback(internal / process / next_tick.js:229:7)

4 个答案:

答案 0 :(得分:2)

request本机支持回调接口,但不返回承诺,这是您在Cloud Function中必须执行的操作。

在以下官方Firebase视频系列中对此进行了说明:https://firebase.google.com/docs/functions/video-series/。尤其要观看三个名为“学习JavaScript的承诺”的视频(第2和第3部分特别关注后台触发的Cloud Functions,但之前确实值得观看第1部分)。

您可以使用request-promisehttps://github.com/request/request-promise)和rp()方法“返回符合Promises / A +的常规承诺”。然后,您将如下修改代码:

import * as functions from 'firebase-functions';

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

const rp = require('request-promise');


exports.sendMessage = functions.firestore.document('comms/{comms}').onCreate((snap, context) => {

    const newValue = snap.data();

    if (newValue) {

        const msg = newValue.msg;


        var options = {
            method: 'POST',
            uri: '....',
            body: msg,
            json: true // Automatically stringifies the body to JSON
        };

        return rp(options)
        .then(parsedBody => {
            // POST succeeded...
            console.log('SUCCESS! Posted', msg);
            return null;
        })
        .catch(err => {
            // POST failed...
            console.log(err);
            return null;
        });

    } else {
        return null;
    }

});

答案 1 :(得分:1)

请求模块没有返回Promise,而是尝试使用回调函数进行响应。

    return request({
  uri: "url",
  method: 'POST',
  body: msg,
  json: true,
  resolveWithFullResponse: true
}, function (error, response, body) {
})

答案 2 :(得分:1)

正如已经在文档中提到的那样,您需要将回调传递给您的请求

var request = require('request');
request('http://www.google.com', function (error, response, body) {
  console.log('error:', error); // Print the error if one occurred
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage.
});

如果要链接请求,可以使用管道

request
  .get('url/img.png')
  .on('response', function(response) {
    console.log(response.statusCode) // 200
    console.log(response.headers['content-type']) // 'image/png'
  })
  .pipe(request.put('url'))

如果您要使用诺言,则可以使用request-promise

var rp = require('request-promise');

rp('http://www.google.com')
    .then(function (htmlString) {
        // Process html...
    })
    .catch(function (err) {
        // Crawling failed...
    });

答案 3 :(得分:0)

request模块仅适用于回调,如果要制作Promisify,则需要这样做

const request = require('request');

const webService = {};

webService.callApi = (url, bodyObj, method) => {
  return new Promise((resolve, reject) => {
    const options = {
      method: method || 'POST',
      url: url,
      headers: {
        'Content-Type': 'application/json',
      },
      body: bodyObj,
      json: true,
    };
    // Error Handler
    const errorMessge = { code: 500, error: 'INTERNAL_SERVER_ERROR' };

    request(options, (error, response, resBody) => {
      if (error) {
        return reject(errorMessge);
      } else if (response.statusCode !== 200) {
        return reject(errorMessge);
      }
      return resolve(resBody);
    });
  });
};

module.exports = webService;