Developer
Developer

Reputation: 2321

Query firestore database for document id

I want to query a firestore database for document id. Currently I have the following code:

db.collection('books').where('id', '==', 'fK3ddutEpD2qQqRMXNW5').get()

I don't get a result. But when I query for a different field it works:

db.collection('books').where('genre', '==', 'biography').get()

How is the name of the document id called?

Upvotes: 167

Views: 224640

Answers (12)

Paulo_els
Paulo_els

Reputation: 1

Any one who need to search in array by id

const arrayData = ["a65s4gs6dg","s6d5gs56dg","s65df4gs56d4"];

 const response = await firestore()
      .collection("products")
      .where(Filter(firestore.FieldPath.documentId(), "in", [...arrayData]))
      .get();

console.log(response)

Upvotes: 0

MickyTonji
MickyTonji

Reputation: 21

If you are looking for more dynamic queries with a helper function, you can simply try this.

import { db} from '@lib/firebase';

import {query, collection, getDocs ,documentId } from "firebase/firestore";

const getResult = async (_value) => {
     const _docId = documentId()
     const _query = [{
        field: _docID,
        operator: '==',
        value: _value
      }]
// calling function
    const result = await getDocumentsByQuery("collectionName", qColl)
    console.log("job result: ", result) 
}

// can accept multiple query args
const getDocumentsByQuery = async (collectionName, queries) => {
    const queryArgs = [];
    queries.forEach(q => {
        queryArgs.push(
            where(q.field, q.operator, q.value)
        );
    });

    const _query = query(collection(db, collectionName), ...queryArgs);
    const querySn = await getDocs(_query);
   
   const documents = [];
    querySn.forEach(doc => {
        documents.push({ id: doc.id, ...doc.data() });
    });

    return documents[0];
};

Upvotes: 2

Elmar
Elmar

Reputation: 4445

Currently only working way for Cloud Functions if you really need to use this way:

// Import firebase-admin
import * as admin from "firebase-admin";

// Use FieldPath.documentId()
admin.firestore.FieldPath.documentId()

 const targetUser = await db.collection("users").where(admin.firestore.FieldPath.documentId() "==", "givenId").get();

Simpler way of this is directly using ID value thru path as there is only one document with given document ID:

const targetUser = await db.doc("users/"+ "givenId").get();

However, you may really need to use it if you are matching given IDs array to the Firebase collection like this:

const admin = require("firebase-admin");

const arr = ["id1", "id2"];
const refArr = arr.map(id => admin.firestore().collection("media").doc(id));

const m = await admin
      .firestore()
      .collection("media")
      .where(admin.firestore.FieldPath.documentId(), "in", refArr)
      .get();

This last example is from this discussion

Upvotes: 11

Carlo Nyte
Carlo Nyte

Reputation: 765

This is the first link that came up when I was looking to solve it in the Golang SDK, so I'll add my solution in case anyone else is looking for it:

package main

import (
    "context"
    "fmt"
    "log"

    "cloud.google.com/go/firestore"
    firebase "firebase.google.com/go/v4"
    "google.golang.org/api/option"
)

type (
    Car struct {
        ID    string
        Name  string  `firestore:"name"`
        Make  string  `firestore:"make"`
        Price float64 `firestore:"make"`
    }
)

func main() {
    ctx := context.Background()

    // Use a service account
    options := option.WithCredentialsFile("PATH/TO/SERVICE/FILE.json")

    // Set project id
    conf := &firebase.Config{ProjectID: "PROJECT_NAME"}

    // Initialize app
    app, err := firebase.NewApp(ctx, conf, options)
    if err != nil {
        log.Fatal(err)
    }

    // Get firestore client
    client, err := app.Firestore(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    collectionRef := client.Collection("CAR_COLLECTION")

    // firestore.DocumentID == "__name__" 
    docSnap, err := collectionRef.Where(firestore.DocumentID, "==", collectionRef.Doc("001")).Get(ctx)
    if err != nil {
        log.Fatal(err)
    }

    // Unmarshall item
    car := Car{}
    docSnap.DataTo(&car)
    car.ID = docSnap.Ref.ID

    // Print car list
    fmt.Println(car)
}

Upvotes: 1

Syed Basim
Syed Basim

Reputation: 476

While everyone is telling to use .get(), which is totally reasonable but it's not always the case.

Maybe you want to filter data based on id (using a where query for example).

This is how you do it in Firebase v9 modular SDK:

import {collection, documentId} from 'firebase/firestore'

const booksRef = collection('books')

const q = query(booksRef, where(documentId(), '==', 'fK3ddutEpD2qQqRMXNW5'))

Upvotes: 44

Mulan
Mulan

Reputation: 135396

June, 2021

The new v9 modular sdk is tree-shakeable and results in smaller compiled apps. It is recommended for all new Firestore apps.

import { doc, getDoc } from "firebase/firestore";

const snap = await getDoc(doc(db, 'books', 'fK3ddutEpD2qQqRMXNW5'))

if (snap.exists()) {
  console.log(snap.data())
}
else {
  console.log("No such document")
}

This is based on the example from the firestore docs

import { doc, getDoc } from "firebase/firestore";

const docRef = doc(db, "cities", "SF");
const docSnap = await getDoc(docRef);

if (docSnap.exists()) {
  console.log("Document data:", docSnap.data());
}
else {
  // doc.data() will be undefined in this case
  console.log("No such document!");
}

You could make this into a helper function

async function getDocument (coll, id) {
  const snap = await getDoc(doc(db, coll, id))
  if (snap.exists())
    return snap.data()
  else
    return Promise.reject(Error(`No such document: ${coll}.${id}`))
}

getDocument("books", "fK3ddutEpD2qQqRMXNW5")

Upvotes: 54

Mejan
Mejan

Reputation: 1276

Just to clear confusion here

Remember, You should use async/await to fetch data whether fetching full collection or a single doc.

async function someFunction(){
 await db.collection('books').doc('fK3ddutEpD2qQqRMXNW5').get();
}

Upvotes: 0

Jürgen Brandstetter
Jürgen Brandstetter

Reputation: 7354

You can use the __name__ key word to use your document ID in a query.

Instead of this db.collection('books').doc('fK3ddutEpD2qQqRMXNW5').get() you can write

db.collection('books').where('__name__', '==' ,'fK3ddutEpD2qQqRMXNW5').get().

In this case you should get an array of length 1 back.

The firebase docs mention this feature in the rules documentation. https://firebase.google.com/docs/reference/rules/rules.firestore.Resource

Upvotes: 76

John
John

Reputation: 104

From Firestore docs for Get a document.

var docRef = db.collection("cities").doc("SF");

docRef.get().then(function(doc) {
    if (doc.exists) {
        console.log("Document data:", doc.data());
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
}).catch(function(error) {
    console.log("Error getting document:", error);
});

Upvotes: 2

Venkat
Venkat

Reputation: 347

You can get a document by its id following this pattern:

firebase
  .firestore()
  .collection("Your collection")
  .doc("documentId")
  .get()
  .then((docRef) => { console.log(docRef.data()) })
  .catch((error) => { })

Upvotes: 15

Denys Mikhalenko
Denys Mikhalenko

Reputation: 4264

I am a bit late, but there is actually a way to do this

db.collection('books').where(firebase.firestore.FieldPath.documentId(), '==', 'fK3ddutEpD2qQqRMXNW5').get()

This might be useful when you're dealing with firebase security rules and only want to query for the records you're allowed to access.

Upvotes: 349

Todd Kerpelman
Todd Kerpelman

Reputation: 17523

Try this:

db.collection('books').doc('fK3ddutEpD2qQqRMXNW5').get()

(The first query is looking for an explicit user-set field called 'id', which probably isn't what you want.)

Upvotes: 148

Related Questions