Ad

Request(...).then Is Not A Function Error When Making A POST Request

I'm trying to create a firebase function that makes a HTTP POST request whenever a new document is created.

This is my code:

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 is not a function at exports.sendMessage.functions.firestore.document.onCreate (/srv/lib/index.js:25:12) at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:127:23) at /worker/worker.js:825:24 at at process._tickDomainCallback (internal/process/next_tick.js:229:7)

Ad

Answer

request supports callback interfaces natively but does not return a promise, which is what you must do within a Cloud Function.

This is explained in the official Firebase video series here: https://firebase.google.com/docs/functions/video-series/. In particular watch the three videos titled "Learn JavaScript Promises" (Parts 2 & 3 especially focus on background triggered Cloud Functions, but it really worth watching Part 1 before).

You could use request-promise (https://github.com/request/request-promise) and the rp() method which "returns a regular Promises/A+ compliant promise". You would then adapt your code as follows:

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;
    }

});
Ad
source: stackoverflow.com
Ad