Skip to content

Document where to get "FieldType" from for @firebase/rules-unit-testing #4555

@amiller-gh

Description

@amiller-gh

[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:

  1. Document that when using @firebase/rules-unit-testing users should import FieldValue directly from the firebase or firebase-admin package rather than relying on @firebase/rules-unit-testing's exported firestore property.

  2. 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-testing exports firestore is mis-leading, especially for people only testing firebase-admin apps! The fact that I could accidentally use the wrong FieldValue by 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-testing can only be firebase utility / factory functions with an optional peer dependency on firebase and firebase-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!
});

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions