Initially I had this code:
const newUserObject = { name: "username", uid: "FirebaseUID", posts: [] }
await Promise.all([
admin.firestore().collection("users").doc("FirebaseUID").set(newUserObject),
mongoDb.collection("users").insertOne(newUserObject)
])
For some reason, this doesn't work and returns the error "cannot encode value". Here is the complete stack trace:
Cannot encode value: 60bb87e2cb98774f01d8bb0b
at Serializer.encodeValue (~/node_modules/@google-cloud/firestore/build/src/serializer.js:168:15)
at Serializer.encodeFields (~/node_modules/@google-cloud/firestore/build/src/serializer.js:57:30)
at Function.fromObject (~/node_modules/@google-cloud/firestore/build/src/document.js:99:53)
at Object.op (~/node_modules/@google-cloud/firestore/build/src/write-batch.js:267:58)
at ~/node_modules/@google-cloud/firestore/build/src/write-batch.js:457:44
at Array.map (<anonymous>)
at WriteBatch._commit (~/node_modules/@google-cloud/firestore/build/src/write-batch.js:457:31)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Promise.all (index 0)
Caused by: Error
at WriteBatch.commit (~/node_modules/@google-cloud/firestore/build/src/write-batch.js:426:23)
at DocumentReference.set (~/node_modules/@google-cloud/firestore/build/src/reference.js:343:14)
at ~/dist/handlers/users.js:75:68
at Generator.next (<anonymous>)
at fulfilled (~/dist/handlers/users.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
The value looks similar to MongoDB ObjectID but I am sure I am not passing that in Firestore object in any way. I checked an answer to a similar question which said you cannot set empty arrays in a new document but that doesn't seem right to me.
If I rewrite my code as follows, it works like charm.
await admin.firestore().collection("users").doc("FirebaseUID").set(newUserObject)
await mongoDb.collection("users").insertOne(newUserObject)
To confirm, nothing is undefined in the object I am trying to set. The issue occurs only when I use it with MongoDB's insertOne in a Promise.all().
Steps to clone the issue:
npm init -y
npm i firebase-admin mongodb
Then copy this code:
const admin = require("firebase-admin")
const mongo = require("mongodb")
const client = mongo.MongoClient("mongodb://localhost:27017/dbname", {
useNewUrlParser: true,
useUnifiedTopology: true,
auth: {
user: "mongodbusername",
password: "mongodbpassword"
}
})
client.connect().then(async () => {
console.log("MongoClient Connected");
admin.initializeApp({
credential: admin.credential.cert("serviceAccountKey.json"),
databaseURL: "https://<project-id>.firebaseio.com"
})
const newUserObject = {name: "NewUser", uid: "userUID", posts: ["PostID1"]}
// UPDATING INDIVIDUALLY
// await admin.firestore().collection("users").doc(newUserObject.uid).set(newUserObject)
// await client.db("lasergg").collection("users").insertOne(newUserObject)
// Works perfectly
// UPDATING IN A PROMISE.ALL()
await Promise.all([
admin.firestore().collection("users").doc(newUserObject.uid).set(newUserObject),
client.db("local").collection("users").insertOne(newUserObject)
])
// Throws error Error: Cannot encode value: 60bdee0a77659f27d493dec8
console.log("All Documents Added!");
})
I modified the source code of Firestore Node SDK here and logged the 'val' parameter [console.log(val, typeof val)] that encodeValue function takes and the output was:
60be04dd53e7965bf4a23173 object
Edit: I logged values being passed in encodeValue() when running promises individually and the output is:
I ran the same when running in Promise.all():
This is what I edited in 'serialier.js':


