Reputation: 57
I'm using firebase-admin 8.6.0 and firebase-functions-test 0.1.6 which has support for Firestore Timestamps in testing (as of 0.1.5 https://github.com/firebase/firebase-functions-test/releases) but am still receiving an error message when trying to use them with test.firestore.makeDocumentSnapshot
.
Can someone help me understand the error in my implementation?
import * as admin from 'firebase-admin';
admin.initializeApp();
const db = admin.firestore();
const settings = { timestampsInSnapshots: true};
db.settings(settings);
const timestamp = admin.firestore.FieldValue.serverTimestamp();
const testingTimestamp1 = admin.firestore.Timestamp.now();
const testingTimestamp2 = admin.firestore.Timestamp.fromDate(new Date);
import * as TestFunctions from 'firebase-functions-test';
const firebaseConfig = {
databaseURL: 'https://...HIDDEN...',
projectId: '...HIDDEN...',
storageBucket: '...HIDDEN...appspot.com',
}
const test = TestFunctions(firebaseConfig, 'service-account-dev.json');
const data({
timestamp,
testingTimestamp1,
testingTimestamp2,
});
const snap = test.firestore.makeDocumentSnapshot(data, path);
const wrapped = test.wrap(processImport);
await wrapped(snap, {params: testParams});
I can't get any of the three timestamp options to work. The latter one I tried learning from @the0rem in https://github.com/firebase/firebase-functions-test/pull/28 but to no avail. I always receive this error:
Cannot encode [object Object]to a Firestore Value. Local testing does not yet support Firestore geo points.`
Upvotes: 0
Views: 1374
Reputation: 96
I was excited when I saw your question because I just faced the same issue. Anyway, here is how I finally solved it. This is the JSON data that I saved from my Firestore database:
const customer = {
username: "A8tAz6wdtucMNKvWSgDkx4bquc2",
timestamp: {
_seconds: 1578762627,
_nanoseconds: 828000000
},
role: "user"
};
Note that timestamp
is just a plain object with two properties: _seconds
and _nanoseconds
. This is where the error "Cannot encode [object Object]to a Firestore Value." comes from i.e. the data object, customer
, contains another object, timestamp
, which Firestore is unable to parse. What we do to solve this is to make sure that timestamp
is not a plain object but an instance of admin.firestore.Timestamp
. And here is how you do that:
const seconds = customer.timestamp._seconds;
const nanosecs = customer.timestamp._nanoseconds;
// create a new Timestamp object passing in the required constructor arguments
const properTimestamp = new admin.firestore.Timestamp(seconds, nanosecs);
customer.timestamp = properTimestamp; // update the timestamp reference in your data object
// Now you can do this
test.firestore.makeDocumentSnapshot(customer, '/users/A8tAz6wdtucMNKvWSgDkx4bquc2')
Now if you do console.log(customer);
you will see that the timestamp object is an instance of admin.firestore.Timestamp
, here is the console output:
// OUTPUT
{
username: 'A8tAz6wdtucMNKvWSgDkx4bquc2',
timestamp: Timestamp { _seconds: 1578762627, _nanoseconds: 828000000 },
role: 'user'
}
PS: I got the answer by checking how Firebase was trying to parse the values/objects in the data. Here is where the parsing was failing and the exception was being thrown (in the file: ../node_modules/firebase-functions-test/lib/providers/firestore.js:165:15
):
if (val instanceof firebase_admin_1.firestore.Timestamp) {
return {
timestampValue: val.toDate().toISOString(),
};
}
Upvotes: 3