user2569905
user2569905

Reputation: 83

Error: Function returned undefined, expected Promise or value

I setup a pubsub function with firebase functions to do some operations every so often in the Firestore. In order to do this I need to make a request to a third party API to get the updated data and then I want to insert that data into the correct collection and document in the Firestore.

const request_promise = require('request-promise')

exports.scheduledFunction = functions.pubsub.schedule('every 2 minutes').onRun((context) => {
    console.log('This will be called every 2 minutes')
    var username = ''
    var password = ''
    var options = {
        url: 'path.to.api.com',
        auth: {
            user: username,
            password: password
        },
        json: true
    }

    request_promise(options)
        .then(function (product) {
            console.log(product.product_id)
            db.collection('products').doc(product.product_id).set(product)
                .then(() => {
                    console.log('Document successfully written')
                })
                .catch(error => {
                    console.log('Error writing product to firestore', error)
                })
        })
        .catch(function (err) {
            console.log('Failed to get product', error)
        })
  });

In the code above if I comment out the call to add the data to the Firestore I the correct product_id prints to the console, so I know the request is working but with it left in I get 'Function returned undefined, expected Promise or value'.

Upvotes: 0

Views: 876

Answers (2)

Sohan
Sohan

Reputation: 6809

With proper promise chaining , this looks more clean

      rp(options)
        .then((product) =>
        {
            console.log(product.product_id)
            // add an implicit return here
            return db.collection('products').doc(product.product_id).set(product)
        })
        .then(() =>
        {
            console.log('Document successfully written')
            // need's to return something here, using a boolean for simplicity
            return true;
        })
        .catch(function (err) 
        {
        console.log('Failed to get product', error);
        // throw will exit the function call
        throw Error('Failed to get product', error);
        });

Also it is not recommended to throw the errors from catch block, catch block are meant to catch errors and handle them and not to throw errors. There are few bits in your code you need to improve but this is not part of this question

Cheers, Happy Coding

Upvotes: 1

mralanlee
mralanlee

Reputation: 489

You're not returning anything at your execution. A console.log isn't treated as a return

request_promise(options)
        .then(function (product) {
            console.log(product.product_id)
            // add an implicit return here
            return db.collection('products').doc(product.product_id).set(product)
                .then(() => {
                    console.log('Document successfully written')
                    // need's to return something here, using a boolean for simplicity
                    return true;
                })
                .catch(error => {
                    console.log('Error writing product to firestore', error)
                    // throw will exit the function call
                    throw Error('Error writing product to firestore', error);
                })
        })
        .catch(function (err) {
            console.log('Failed to get product', error);
            // throw will exit the function call
            throw Error('Failed to get product', error);
        })

Upvotes: 1

Related Questions