firebase / firebase-functions-test

MIT License
232 stars 48 forks source link

Error: Cannot encode [object Object]to a Firestore Value. Local testing does not yet support Firestore geo points. #47

Closed bradleymackey closed 3 years ago

bradleymackey commented 4 years ago

Version info

firebase-functions-test: 0.1.6

firebase-functions: 3.2.0

firebase-admin: NOT REQUIRED

@firebase/testing: 0.13.3

Test case

const functions = require('firebase-functions');
const test = require('firebase-functions-test')();
const firebase = require('@firebase/testing');

// example function trigger
const userCreated = functions.firestore
    .document('/users/{userID}')
    .onCreate(async (snap, context) => {
        console.log(`user created: ${snap.id}!`);
    });

// wrap the function
const wrapped = test.wrap(userCreated);

// make a snapshot and execute
const newUser = {
    name: 'Tom Jones',
    location: new firebase.firestore.GeoPoint(1.123, 51.123)
};
const snap = test.firestore.makeDocumentSnapshot(newUser, '/users/1234');
const prom = wrapped(snap);
prom.then(() => {
    console.log('complete');
})
.catch(error => {
    console.error(error);
});

Steps to reproduce

Execute test case provided, error is thrown during the call to test.firestore.makeDocumentSnapshot.

Expected behavior

Snapshot created successfully, function is execution is emulated as is trigger has occurred.

Actual behavior

Call to test.firestore.makeDocumentSnapshot fails due to GeoPoint in the data model.

Produces error:

Error: Cannot encode [object Object]to a Firestore Value. Local testing does not yet support Firestore geo points.
tzvc commented 4 years ago

Any updates on this ? This is a pretty important feature

vladimirbrasil commented 4 years ago

"Error: Cannot encode [object Object]to a Firestore Value. Local testing does not yet support Firestore geo points"

Same error, but I don't use firestore.GeoPoint in my snapshot. I use firestore.GeoPoint in only one collection, and I am not testing this collection. The collection that I am testing updates the collection that uses GeoPoints, but I am not even testing this side effect.

The issue - and the solution - may be bigger than only using GeoPoints in the tested collection.

UPDATE: this message only occurs when testing any "onWrite" firestore trigger function. I changed one of this "onWrite" functions to trigger "onCreate" (instead of "onWrite") - and suddenly the tests run as expected.

Maybe the failure comes from the different setup for onWrite:

onWrite setup (source):

const beforeSnap = test.firestore.makeDocumentSnapshot({...}, yourDocRef) const afterSnap = test.firestore.makeDocumentSnapshot({...}, yourDocRef) const change = test.makeChange(beforeSnap, afterSnap) const after = test.firestore.makeDocumentSnapshot(change, docRef)

onCreate setup: const after = test.firestore.makeDocumentSnapshot({...}, yourDocRef);

Both setups run this: await wrapped(after)

eschirtz commented 3 years ago

Any updates on this? I don't use GeoPoints at all and this is failing as @vladimirbrasil describes

bradleymackey commented 3 years ago

This also affects (I think all) of the firestore.FieldValues. I'd like to suggest that this issue is upgraded to 'bug' rather than 'feature request', because these types are pretty fundamental to Firestore testing. My current workaround is to only use this library for testing HTTPS functions, and just not use it for Firestore.

WORKAROUND Instead, just use the Firestore and Functions emulator (with firebase emulators:start) and manually add document into Firestore. Then, add a listener to a given document to confirm that the side-effects of a function were performed as expected.

melchoir55 commented 3 years ago

Fyi to anyone tripping over this. This can happen when you are trying to write invalid types to firestore fields. The error message is just poorly written. It doesn't necessarily have anything to do with geo points.

lloydrichards commented 3 years ago

Has this in any way been solved? I have the exact issue with trying to mock .onUpdate with documents containing GeoPoints. I can get the .makeDocumentSnapshot() to pass if I pass in an object with {latitude,longitude} but in the function I'm specifically using the isEqual() of the GeoPoint to make comparisons. Resulting in the test failing cause isEqual isn't defined on my mock.

Its kind of an important feature of a testing library to be able to test the convoluted classes that they make for us 😅

ChromeQ commented 3 years ago

I hit this error too and my document does not have geo points. Even a document reference and timestamp cause this. Digging into the makeDocumentSnapshot it checks if the field is an instanceof DocumentReference from firebase-admin. This fails and falls through to the error but I can't explain why as my documents were created using the same instance of firebase firestore-admin. The same is true for checking instanceof Timestamp, the if check fails and falls through to the error