Reputation: 682
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
Upvotes: 3
Views: 1842
Reputation: 83058
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();
});
});
Upvotes: 6