-
Notifications
You must be signed in to change notification settings - Fork 986
Description
[REQUIRED] Describe your environment
- Operating System version: MacOS
- Browser version: N/A
- Firebase SDK version:
@firebase/rules-unit-testing@1.2.2,firebase-admin@9.5.0,firebase@8.2.9,firebase-tools@9.5.0 - Firebase Product: firestore
[REQUIRED] Describe the problem
@firebase/rules-unit-testing is the sanctioned testing package for interacting with firebase. The documentation allows you to create both client apps via initializeApp and admin apps via initializeAdminApp. While testing, if you retrieve the FieldValue object in an incorrect way, you get the very helpful Detected an object of type "FieldValue" that doesn't match the expected instance error.
In my use case, I am testing admin apps. I was trying to use the FieldValue object delivered on FirebaseTesting.firestore.FieldValue. However, the FieldValue object delivered by the main export of @firebase/rules-unit-testing comes from firebase not from firebase-admin! It turns out firebase-admin is lazy required inside of initializeAminApp while the default export of FirebaseTesting is a (kind-of) monkeypatched version of firebase.
There are two solutions for this user pitfall here, one short term, and one longer term, if technically possible:
-
Document that when using
@firebase/rules-unit-testingusers should importFieldValuedirectly from thefirebaseorfirebase-adminpackage rather than relying on@firebase/rules-unit-testing's exportedfirestoreproperty. -
Not sure if this is technically possible, and would have to wait for a major version bump regardless, but the fact that
@firebase/rules-unit-testingexportsfirestoreis mis-leading, especially for people only testingfirebase-adminapps! The fact that I could accidentally use the wrongFieldValueby using a public API on the package I'm relying on as a factory for my test Firebase apps is not ideal :) Perhaps@firebase/rules-unit-testingcan only be firebase utility / factory functions with an optional peer dependency onfirebaseandfirebase-admin. If you need anything else from the packages, you import it youself.
Reproduction
Admin app with firebase testing's FieldValue
import * as fireTest from '@firebase/rules-unit-testing';
// Note: Admin App
const app = fireTest.initializeAdminApp({ projectId: 'my-project' });
const db = app.firebase();
db.set('my/document', {
value: fireTest.firestore.FieldValue.increment(1), // Errors!
});Client app with firebase testing's FieldValue
import * as fireTest from '@firebase/rules-unit-testing';
// Note: Client App
const app = fireTest.initializeApp({ projectId: 'my-project' });
const db = app.firebase();
db.set('my/document', {
value: fireTest.firestore.FieldValue.increment(1), // Works?!
});Admin app with firebase-admin's FieldValue
import * as fireTest from '@firebase/rules-unit-testing';
import Firebase from 'firebase-admin';
// Note: Admin App
const app = fireTest.initializeAdminApp({ projectId: 'my-project' });
const db = app.firebase();
db.set('my/document', {
value: Firebase.firestore.FieldValue.increment(1), // Works!
});Client app with firebase's FieldValue
import * as fireTest from '@firebase/rules-unit-testing';
import Firebase from 'firebase';
// Note: Client App
const app = fireTest.initializeApp({ projectId: 'my-project' });
const db = app.firebase();
db.set('my/document', {
value: Firebase.firestore.FieldValue.increment(1), // Works!
});