Firebase-admin-node: FieldPath.documentId() must be a string or a DocumentReference

Created on 23 Jun 2020  Â·  22Comments  Â·  Source: firebase/firebase-admin-node

  • Operating System version: macOS Catalina
  • firebase-admin version 8.12.1
  • Firebase Product: firestore
  • Node.js version: 10

Problem

This query doesn't work when using firebase-admin, throwing an error:

'... FieldPath.documentId() must be a string or a DocumentReference'

import admin from 'firebase-admin'

const menus = await admin
  .firestore()
  .collection('menus')
  .where(admin.firestore.FieldPath.documentId(), 'in', [
    'cUKi4Kj42LOcLsqBZOBhM',
  ])
  .get()

This issue has been reported and apparently resolved in nodejs-firestore (https://github.com/googleapis/nodejs-firestore/issues/990)

Same query using the @google-cloud/firestore package works:

import { FieldPath, Firestore } from '@google-cloud/firestore'

const firestore = new Firestore()

const menus = await firestore
  .collection('menus')
  .where(FieldPath.documentId(), 'in', ['cUKi4Kj42LOcLsqBZOBhM'])
  .get()

firestore

All 22 comments

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

+1

Our dependency on Firestore is defined as "@google-cloud/firestore": "^3.0.0",. So if you reinstall the package from the scratch NPM should pull the latest Firestore library with the required fix (v3.7.3 and up).

Closing as this has been fixed and released. If this is still an issue in the latest @google-cloud/firestore, please comment and we can re-open.

Sorry, I'm a little lost here.
The problem was reported for admin sdk https://firebase.google.com/docs/admin/setup running on emulator.
Are we supposed to stop using admin sdk?
Can you please provide guidance?
I'm not sure how to proceed, replace admin-sdk or have this working as expected on emulator.
is it documented anywhere?
Thank you very much.

@robsoncombr Admin SDK just uses @google-cloud/firestore under the hood. So as long as that dependency is up-to-date there's no other action items.

Hello @hiranya911 thank you for the reply.
I have uninstalled / reinstalled firebase-admin, I get version "^8.12.1"

When I check google-cloud/firestore dependencies inside its packages.json seems to be ok:
$ grep firestore functions/node_modules/firebase-admin/package.json
"@google-cloud/firestore": "^3.0.0",
"@google-cloud/firestore": "^3.0.0",

However, the problem remains when running on emulator.
await admin.firestore().collection('tenants').where(admin.firestore.FieldPath.documentId(), 'in', tenants)

Results in:

Unhandled error Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was "[object Object]".

I still believe we have some sort of problem that affects at least emulator, can I get this blessed?

I needed to remove and recreate the lock file to get the latest version of @google-cloud/firestore. It all works now.

I'm not sure how you guys are fixing it, mine does not work. Any guidance is appreciated. Thanks.

Check what version of @google-cloud/firestore is specified in your lock file. It has to be "3.7.3" or higher.

Take a look at this.

firebase/functions

$ grep firebase package.json
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
"firebase-admin": "^8.12.1",
"firebase-functions": "^3.7.0",
"firebase-functions-test": "^0.2.0"

firebase/functions

$ grep firestore package.json

firebase/functions

$ grep firestore package-lock.json
"@google-cloud/firestore": {
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-3.8.6.tgz",
"@google-cloud/firestore": "^3.0.0",

firebase/functions

$ grep firebase package-lock.json
"@firebase/app-types": {
"resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.1.tgz",
"@firebase/auth-interop-types": {
"resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.5.tgz",
"@firebase/component": {
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.14.tgz",
"@firebase/util": "0.2.49",
"@firebase/database": {
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.6.5.tgz",
"@firebase/auth-interop-types": "0.1.5",
"@firebase/component": "0.1.14",
"@firebase/database-types": "0.5.1",
"@firebase/logger": "0.2.5",
"@firebase/util": "0.2.49",
"@firebase/database-types": {
"resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.5.1.tgz",
"@firebase/app-types": "0.6.1"
"@firebase/logger": {
"resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.5.tgz",
"@firebase/util": {
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.49.tgz",
"firebase-admin": {
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-8.12.1.tgz",
"@firebase/database": "^0.6.0",
"firebase-functions": {
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.7.0.tgz",
"firebase-functions-test": {
"resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.2.1.tgz",

What's the output of npm ls @google-cloud/firestore?

/firebase/functions
└─┬ [email protected]
└── @google-cloud/[email protected]

Hey @robsoncombr. Can you provide us a repro that we can locally test? Ideally a zipped up version of your project.

I have done a lot of troubleshooting.
The last was to uninstall firebase-admin, delete npm lock file and re-install firebase-admin.
No luck.

I have the latest version installed so I noticed it is requiring firestore 3.0.0
https://github.com/firebase/firebase-admin-node/blob/master/package.json
Isn't it the issue?

My project is huge, maybe I could try to start a new one from scratch to run only this.

A fast explaining, I'm running it from a function call.

I create a function using firebase-admin with app initialized using service credentials.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
(..init..)
exports.testFunction = functions.region('us-east1').https.onCall(async (data, context) => {
    const tenants = [<ids-here>];
    await admin.firestore().collection('tenants').where(admin.firestore.FieldPath.documentId(), 'in', tenants)
      .get().then(s => { console.log('IN => ', s.docs) });
});

I run it using localhost emulator.

Then I call from app:
await firebaseApp.functions('us-east1').httpsCallable('auth-testFunction')().catch(e => console.error(e))

This causes the error on the emulator console:

Unhandled error Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was "[object Object]".

It doesn't reproduce to us. It also seems other developers managed to get it working by simply reinstalling the dependencies. We will need some sort of a test app to repro this. If you can provide a simplified version of your project that would be most helpful.

Still having this issue, using both @google/cloud-firestore and firebase-admin throwing this error:
Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was "1"

package.json:
"dependencies": { "@firebase/testing": "^0.20.9", "@google-cloud/firestore": "^4.1.1", "@types/cors": "^2.8.6", "body-parser": "^1.19.0", "cors": "^2.8.5", "express": "^4.17.1", "firebase-admin": "^9.0.0", "firebase-functions": "^3.6.1", "firebase-tools": "^8.6.0", "nodemon": "^2.0.4" },

I tried uninstalling, installing both dependencies, deleting node_modules and installing everything all over again, no luck.

Also running using local emulator.

@13dante04 Can you paste your code snippet? I wonder where the "1" comes from.

Also if you could provide the output of npm list | grep firestore that might help us. This is very likely a dependency conflict.

Well, a fast for the record note, I'm following you and I still have the issue but the suggested solution never resolved the issue. Good that someone else is experiencing the same issue.

ubuntu@codi:/codi/dev/controledigital.app/firebase/functions$ npm list | grep firestore
│ ├─┬ @google-cloud/[email protected]
ubuntu@codi:/codi/dev/controledigital.app/firebase/functions$ npm ls @google-cloud/firestore
functions@ /codi/dev/controledigital.app/firebase/functions
└─┬ [email protected]
└── @google-cloud/[email protected]

I have just reproduced to confirm, from the debug log:

[info] > Unhandled error Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was "[object Object]". {"user":"Unhandled error Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was \"[object Object]\".","metadata":{"emulator":{"name":"functions"},"function":{"name":"auth-getCustomToken"},"message":"\u001b[90m> \u001b[39m Unhandled error Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was \"[object Object]\"."}}

[info] > at CollectionReference.validateReference (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1342:19) {"user":" at CollectionReference.validateReference (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1342:19)","metadata":{"emulator":{"name":"functions"},"function":{"name":"auth-getCustomToken"},"message":"\u001b[90m> \u001b[39m at CollectionReference.validateReference (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1342:19)"}}

[info] > at value.map.el (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1048:46) {"user":" at value.map.el (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1048:46)","metadata":{"emulator":{"name":"functions"},"function":{"name":"auth-getCustomToken"},"message":"\u001b[90m> \u001b[39m at value.map.el (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1048:46)"}}

[info] > at Array.map () {"user":" at Array.map ()","metadata":{"emulator":{"name":"functions"},"function":{"name":"auth-getCustomToken"},"message":"\u001b[90m> \u001b[39m at Array.map ()"}}

[info] > at CollectionReference.where (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1048:31) {"user":" at CollectionReference.where (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1048:31)","metadata":{"emulator":{"name":"functions"},"function":{"name":"auth-getCustomToken"},"message":"\u001b[90m> \u001b[39m at CollectionReference.where (/codi/dev/controledigital.app/firebase/functions/node_modules/@google-cloud/firestore/build/src/reference.js:1048:31)"}}

[info] > at exports.getCustomToken.functions.region.https.onCall (/codi/dev/controledigital.app/firebase/functions/auth/getCustomToken.js:94:51) {"user":" at exports.getCustomToken.functions.region.https.onCall (/codi/dev/controledigital.app/firebase/functions/auth/getCustomToken.js:94:51)","metadata":{"emulator":{"name":"functions"},"function":{"name":"auth-getCustomToken"},"message":"\u001b[90m> \u001b[39m at exports.getCustomToken.functions.region.https.onCall (/codi/dev/controledigital.app/firebase/functions/auth/getCustomToken.js:94:51)"}}

[info] > at process._tickCallback (internal/process/next_tick.js:68:7) {"user":" at process._tickCallback (internal/process/next_tick.js:68:7)","metadata":{"emulator":{"name":"functions"},"function":{"name":"auth-getCustomToken"},"message":"\u001b[90m> \u001b[39m at process._tickCallback (internal/process/next_tick.js:68:7)"}}

My repro command is simple:
const tenants = [<ids-here>]; await admin.firestore().collection('tenants').where(admin.firestore.FieldPath.documentId(), 'in', tenants).get().then(s => { console.log('IN => ', s.docs) });

Maybe we could just have someone from Firebase to try it from scratch on their side, simply install emulator, write a function that uses FieldPath.documentId() and see the error.

Cheers.

I tried the following in a standalone script, and it worked without any hiccups.

# File: run.js
const admin = require('firebase-admin');

admin.initializeApp();

const tenants = ['foo', 'bar'];
admin.firestore().collection('tenants')
  .where(admin.firestore.FieldPath.documentId(), 'in', tenants).get()
  .then(s => {
    s.docs.forEach((doc) => {
      console.log(doc.data());
    })
  });
$ npm install firebase-admin
$ node run.js
{ name: 'bar' }
{ name: 'foo' }

Can you repro the issue in a similar minimalistic script?

@13dante04 I'm fairly sure the problem is in your code. I can reproduce your exact error when the list of IDs contains the integer 1:

const tenants = [1, 2];
admin.firestore().collection('tenants')
  .where(admin.firestore.FieldPath.documentId(), 'in', tenants).get()
  .then(s => console.log(s.docs));
/Users/hkj/Projects/firebase-admin-node/fsissue/node_modules/@google-cloud/firestore/build/src/reference.js:1323
            throw new Error('The corresponding value for FieldPath.documentId() must be a ' +
            ^

Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was "1".
    at CollectionReference.validateReference (/Users/hkj/Projects/firebase-admin-node/fsissue/node_modules/@google-cloud/firestore/build/src/reference.js:1323:19)

Document IDs must be strings. Therefore please make sure the list of IDs passed in to the IN query only contains strings.

@robsoncombr you might be having the same issue. From your error message it seems some of the values in your tenants list are objects:

Unhandled error Error: The corresponding value for FieldPath.documentId() must be a string or a DocumentReference, but was "[object Object]".

Having the same issue with latest firebase-admin: 9.4.2.

My firestore references some data from a psql db so the ids are numbers toStringed().

Was this page helpful?
0 / 5 - 0 ratings