Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js - Firebase Cloud Functions batch write is not working

I am trying to get currency exchange rates from fixer.io (in JSON format) and store it into firestore using the firebase cloud functions. The code works great if I did not commit the batch, it is able to show the results into the console. But when I commit the batch, there is nothing being created in my firestore and there are no error logs shown in the console except for the usual Function executed, finished with status "ok"

Below is my Cloud Function's code. I have included an API key in the request method too, feel free to use it as I only use it for testing purposes

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const firestore = functions.firestore;
const db = admin.firestore();

const FieldValue = require('firebase-admin').firestore.FieldValue;

const request = require('request');

exports.testCurrency = firestore
        .document('trigger/{docId}')
        .onUpdate((change, context) => {
            return request('http://data.fixer.io/api/latest?access_key=aeb14ea1a7db3bbf08edc96a41bd4be1', (error, response, body) => {
                if(error){
                    return console.log('error:', error);
                }

                body = JSON.parse(body);
                console.log('response: ', response.statusCode);

                var batch = db.batch();

                Object.keys(body["rates"]).forEach((key, index) => {
                                console.log(key,body["rates"][key]);
                                // key: the name of the object key
                                // index: index of key
                                var batchRef = db.collection('currencyRates').doc(key);
                                batch.set(batchRef, {
                                    base: body.base,
                                    code: key,
                                    value: body["rates"][key],
                                    dateCreated: FieldValue.serverTimestamp() 
                                });
                            });

                return batch.commit().then( () => {
                            return console.log("im done");
                        }).catch((err) => {
                            return console.log('Error batch: ', err);
                        });
            });
    });

This is the results in JSON format. The rates array's size is about 168 if it matters.

{
    success: true,
    timestamp: 1539162846,
    base: "EUR",
    date: "2018-10-10",
    rates: {
        AED: 4.21958,
        AFN: 86.890666,
        ALL: 125.212079,
        AMD: 555.643524,
        ANG: 2.029407,
        AOA: 348.895181,
        ARS: 42.90457,
        AUD: 1.619478,
        AWG: 2.068292,
        AZN: 1.955714,
        BAM: 1.953077,
        BBD: 2.288159,
        BDT: 96.49329,
        BGN: 1.955774,
        BHD: 0.433066,
        BIF: 2030.211654,
        BMD: 1.148732,
        BND: 1.619944,
        BOB: 7.900117,
        BRL: 4.269034,
        BSD: 1.143126,
        BTC: 0.000176,
        BTN: 85.26911,
        BWP: 12.46839,
        BYN: 2.462135,
        BYR: 22515.148904,
        BZD: 2.297751,
        CAD: 1.489098,
        CDF: 1866.689969,
        CHF: 1.14073,
        CLF: 0.025961,
        CLP: 781.999328,
        CNY: 7.951635,
        COP: 3515.235059,
        CRC: 671.686818,
        CUC: 1.148732,
        CUP: 30.4414,
        CVE: 110.879642,
        CZK: 25.839465,
        DJF: 204.152281,
        DKK: 7.46024,
        DOP: 57.019033,
        DZD: 136.351778,
        EGP: 20.59275,
        ERN: 17.230769,
        ETB: 31.762606,
        EUR: 1,
        FJD: 2.46248,
        FKP: 0.873014,
        GBP: 0.873927,
        GEL: 3.0154,
        GGP: 0.873866,
        GHS: 5.645042,
        GIP: 0.873123,
        GMD: 56.879486,
        GNF: 10343.241533,
        GTQ: 8.809053,
        GYD: 236.724948,
        HKD: 9.002495,
        HNL: 27.485141,
        HRK: 7.421727,
        HTG: 80.234922,
        HUF: 324.873057,
        IDR: 17489.331151,
        ILS: 4.163562,
        IMP: 0.873866,
        INR: 85.253156,
        IQD: 1364.17679,
        IRR: 48367.364525,
        ISK: 132.609588,
        JEP: 0.873866,
        JMD: 152.476977,
        JOD: 0.815388,
        JPY: 130.030675,
        KES: 116.079279,
        KGS: 79.626322,
        KHR: 4654.771655,
        KMF: 492.432692,
        KPW: 1033.875108,
        KRW: 1306.533994,
        KWD: 0.348762,
        KYD: 0.952753,
        KZT: 425.277826,
        LAK: 9754.698885,
        LBP: 1735.676925,
        LKR: 196.53612,
        LRD: 180.064096,
        LSL: 16.892084,
        LTL: 3.391907,
        LVL: 0.694857,
        LYD: 1.586976,
        MAD: 10.897331,
        MDL: 19.430783,
        MGA: 4015.335983,
        MKD: 61.577767,
        MMK: 1791.849588,
        MNT: 2946.506569,
        MOP: 9.22564,
        MRO: 410.097772,
        MUR: 39.701904,
        MVR: 17.702453,
        MWK: 835.353456,
        MXN: 21.915972,
        MYR: 4.77302,
        MZN: 69.463749,
        NAD: 16.909355,
        NGN: 416.162676,
        NIO: 36.701418,
        NOK: 9.464513,
        NPR: 136.021946,
        NZD: 1.778777,
        OMR: 0.442245,
        PAB: 1.143293,
        PEN: 3.82126,
        PGK: 3.839121,
        PHP: 62.253815,
        PKR: 147.026549,
        PLN: 4.307079,
        PYG: 6749.384482,
        QAR: 4.182653,
        RON: 4.663511,
        RSD: 118.365442,
        RUB: 76.049784,
        RWF: 1012.733695,
        SAR: 4.307918,
        SBD: 9.226628,
        SCR: 15.645159,
        SDG: 20.655924,
        SEK: 10.446081,
        SGD: 1.588583,
        SHP: 1.517356,
        SLL: 9591.913264,
        SOS: 667.413258,
        SRD: 8.567209,
        STD: 24504.701795,
        SVC: 10.00385,
        SYP: 591.597066,
        SZL: 17.114991,
        THB: 37.862491,
        TJS: 10.775738,
        TMT: 4.020562,
        TND: 3.260443,
        TOP: 2.638176,
        TRY: 7.025433,
        TTD: 7.705815,
        TWD: 35.617013,
        TZS: 2626.001928,
        UAH: 32.080682,
        UGX: 4336.463361,
        USD: 1.148732,
        UYU: 37.80484,
        UZS: 9353.378599,
        VEF: 285482.841016,
        VND: 26824.042963,
        VUV: 131.850501,
        WST: 3.039038,
        XAF: 655.064673,
        XAG: 0.080115,
        XAU: 0.000968,
        XCD: 3.104506,
        XDR: 0.825483,
        XOF: 654.949648,
        XPF: 119.089105,
        YER: 287.142825,
        ZAR: 16.841745,
        ZMK: 10339.970197,
        ZMW: 14.261535,
        ZWL: 370.299545
    }
}

UPDATE: my firebase account is currently on Blaze Plan (Pay as You Go) because I found a post on SO that says free plan won't allow 3rd party access

like image 213
the newbie coder Avatar asked Aug 30 '26 06:08

the newbie coder


1 Answers

Your problem comes from the fact that a call with request does not return a promise, while in Cloud Functions triggered by background events (like .onUpdate() for Firestore) you must return a Promise. Watch this official video series for more details: https://firebase.google.com/docs/functions/video-series/ (in particular the 3 videos titled "Learn JavaScript Promises", which explain it very well).

So you need to use an interface wrapper for request, like request-promise.

The following modified code should work:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const firestore = functions.firestore;
const db = admin.firestore();

const FieldValue = require('firebase-admin').firestore.FieldValue;

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

exports.testCurrency = firestore
        .document('trigger/{docId}')
        .onUpdate((change, context) => {

            var options = {
                url: 'http://data.fixer.io/api/latest?access_key=aeb14ea1a7db3bbf08edc96a41bd4be1',
                method: 'GET'
            };

            return rp(options)
            .then(body => {

                body = JSON.parse(body);

                var batch = db.batch();

                Object.keys(body["rates"]).forEach((key, index) => {
                            console.log(key,body["rates"][key]);
                            // key: the name of the object key
                            // index: index of key
                            var batchRef = db.collection('currencyRates').doc(key);
                            batch.set(batchRef, {
                                base: body.base,
                                code: key,
                                value: body["rates"][key],
                                dateCreated: FieldValue.serverTimestamp() 
                            });
                        });

                return batch.commit();

        });

    });
like image 198
Renaud Tarnec Avatar answered Aug 31 '26 21:08

Renaud Tarnec



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!