Reputation: 51
I recent wiped my computer and reinstall everything. It was working fine before I factor reset but it's not allowing me to use optional chaining now. I have already specified node engine v14 in package.json. If someone can let me know why it doesn't work anymore, that will be awesome!
node -v 14.16.1
npm -v 8.1.2
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔ functions: required API cloudbuild.googleapis.com is enabled
✔ functions: required API cloudfunctions.googleapis.com is enabled
Error: Error occurred while parsing your function triggers.
/Users/ivanchau/dev/autotransportappfbcloud/functions/db/orders/onWrite.f.js:7
const _pm = order?.payment_method;
^
SyntaxError: Unexpected token '.'
at wrapSafe (internal/modules/cjs/loader.js:1052:16)
at Module._compile (internal/modules/cjs/loader.js:1100:27)
at Module._compile (pkg/prelude/bootstrap.js:1394:32)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1156:10)
at Module.load (internal/modules/cjs/loader.js:984:32)
at Function.Module._load (internal/modules/cjs/loader.js:877:14)
at Module.require (internal/modules/cjs/loader.js:1024:19)
at Module.require (pkg/prelude/bootstrap.js:1338:31)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (/Users/ivanchau/dev/autotransportappfbcloud/functions/index.js:49:31)
package.json
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"dependencies": {
"@googlemaps/google-maps-services-js": "^2.3.1",
"algoliasearch": "^4.8.4",
"camelcase": "^5.3.1",
"email-templates": "^6.0.0",
"es6-promise-pool": "^2.5.0",
"excel4node": "^1.7.2",
"firebase-admin": "^9.4.2",
"firebase-functions": "^3.16.0",
"glob": "^7.1.4",
"lodash": "^4.17.19",
"moment": "^2.24.0",
"moment-timezone": "^0.5.25",
"nodemailer": "^6.2.1",
"pug": "^2.0.3"
},
"private": true,
"engines": {
"node": "14"
},
"devDependencies": {
"eslint": "^7.19.0",
"eslint-config-prettier": "^7.2.0",
"eslint-plugin-prettier": "^3.3.1",
"prettier": "^2.2.1"
}
}
eslintrc.json
{
"env": {
"es6": true,
"node": true
},
"extends": [
"plugin:prettier/recommended"
],
"plugins": ["prettier"],
"parserOptions": {
"sourceType": "module"
},
"rules": {
"prettier/prettier": ["error", {
"endOfLine":"auto"
}]
}
}
Code Sample
const { log } = require("firebase-functions/lib/logger");
const functions = require("firebase-functions");
const moment = require("moment-timezone");
const admin = require("../../firebaseConn.js");
function updateTotal(order, negative = false) {
const _pm = order?.payment_method;
const _isConfirmed = ["confirmed", "waiting"].includes(
order.status.toLowerCase()
);
const _cost = parseFloat(_isConfirmed && _pm === "Cash" ? order.cost : 0);
const _receipt = parseFloat(
_isConfirmed && _pm === "Cash" ? order.receipt : 0
);
const _no_pay_cost = parseFloat(
_isConfirmed && ["Credit Card", "不用收錢"].includes(_pm) ? order.cost : 0
);
const _offset = negative ? -1 : 1;
const _vals = {
cost: admin.firestore.FieldValue.increment(_cost * _offset),
receipt: admin.firestore.FieldValue.increment(_receipt * _offset),
no_pay_cost: admin.firestore.FieldValue.increment(_no_pay_cost * _offset),
};
const dateTime = moment(order.dateTime?.toDate()).tz("America/Toronto");
const y = dateTime.format("YYYY"),
m = dateTime.format("M"),
m0 = dateTime.format("MM"),
d = dateTime.format("DD");
const totalRef = admin.firestore().collection("orderTotal");
const monthlyTotal = {
[`${y}-${m}`]: _vals,
};
const dailyTotal = {
[`${y}-${m}`]: {
[`${y}-${m0}-${d}`]: _vals,
},
};
log(monthlyTotal);
log(dailyTotal);
const t1 = totalRef.doc("monthlyTotal").set(monthlyTotal, { merge: true });
const t2 = totalRef.doc("dailyTotal").set(dailyTotal, { merge: true });
return Promise.all([t1, t2]);
}
module.exports = functions.firestore
.document("orders/{oid}")
.onWrite((change, context) => {
const _oldOrder = change.before.data();
const _newOrder = change.after.data();
const _oid = context.params.oid;
const promises = [];
if (_oldOrder) {
const t1 = updateTotal(_oldOrder, true);
promises.push(t1);
log(`Deducted old order from monthly total! ${_oid}`);
}
if (_newOrder) {
const t2 = updateTotal(_newOrder);
promises.push(t2);
log(`Added monthly total! ${_oid}`);
}
return Promise.all(promises);
});
Upvotes: 2
Views: 1344
Reputation: 982
The documentation says:
Optional chaining cannot be used on a non-declared root object, but can be used with an undefined root object.
In your code, looks like "_prg" is not declared?
moment(_prg?.startDate?.toDate());
Upvotes: 0
Reputation: 1170
The problem with using “Optional Chaining” is noted in a few different public issues. For example, in Github issue and there is also a stackoverflow Answer on this. The answer suggested in stackoverflow seems the most appropriate, as Firebase implementation seems to be not interpreting the expression as condensed and expanding it appropriately.
This is known to Google and the engineers are working on it, thus It is best to formulate the expression without chaining until this feature is released in Firebase Functions.
Upvotes: 2