Firebase-js-sdk: query using collection.limit() returns entire collection - limit remains set to null

Created on 19 May 2018  路  5Comments  路  Source: firebase/firebase-js-sdk

  • Operating System version: Mac OS 10.11.6 using Node v8.11.1 with Vue.js webpack project

  • Firebase SDK version:

"dependencies": {
    "@firebase/app": "^0.3.2",
    "@firebase/auth": "^0.5.2",
    "@firebase/firestore": "^0.5.3"
  }
  • Firebase Product: firestore

[REQUIRED] Describe the problem

Invoking the .limit() method on a collection fails to set the limit. Instead the entire collection is returned.

Steps to reproduce:

Create a collection in a Firestore and add 4 items. Set up a limit query using Node.js Client using similar code shown below.

Relevant Code:

try {
      let colRef = firebase.firestore().collection('stuff');

      colRef.limit(2);

      let querySnapshot = await colRef.get(); // _query.limit = null so returns the entire collection


https://stackblitz.com/edit/firebase-issue-sandbox-zw5mmw

firestore

Most helpful comment

I'm not sure I understand what you're asking. Your example does:

  col.limit(limit);  // THIS IS IGNORED
  return col.get(); // returns the entire collection

You need to do:

  const query = col.limit(limit);
  return query.get();

Collection and Query objects are immutable in Firestore. You cannot change them. You can only call methods that return new (mutated) instances.

All 5 comments

This problem seems to arise as a result of a broken fluent interface, creating new Query objects for each link in the chain.

https://github.com/firebase/firebase-js-sdk/blob/master/packages/firestore/src/core/query.ts#L146-L166

This works:

let colRef = firebase.firestore().collection('things');
let query = colRef.orderBy('created', 'desc').limit(2);

But, this doesn't because of the change in the call site of the method.

let colRef = firebase.firestore().collection('things');
let query = colRef.orderBy('created', 'desc');
query.limit(2);

@andyfusniak This is the intended behavior of the API. You build up a query through chaining operations together. We explicitly want you to be able to do things like:

const todos = db.collection('todos');
...
const importantTodos = todos.where('priority', '>', 8);
const overdueTodos = todos.where('due_date', '<=', new Date());

And so it's important that the query operators don't modify the original query. Hope this helps!

Ok, I understand why you chose to create a new object for each link in the chain and it would appear would have no connection to my original problem.

However, the limit is still not being set (see the example code link where the entire collection is returned). Could you explain how to build a query using limit when the limit is optionally passed as a parameter?

I'm not sure I understand what you're asking. Your example does:

  col.limit(limit);  // THIS IS IGNORED
  return col.get(); // returns the entire collection

You need to do:

  const query = col.limit(limit);
  return query.get();

Collection and Query objects are immutable in Firestore. You cannot change them. You can only call methods that return new (mutated) instances.

Thanks @mikelehen. I got it now.

Was this page helpful?
0 / 5 - 0 ratings