Skip to content

startAt to support key #1114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bob-lee opened this issue Aug 18, 2017 · 6 comments
Closed

startAt to support key #1114

bob-lee opened this issue Aug 18, 2017 · 6 comments

Comments

@bob-lee
Copy link
Contributor

bob-lee commented Aug 18, 2017

Version info

Angular: 4.3.5

Firebase: 4.3.0

AngularFire: 4.0.0-rc.2

Other (e.g. Ionic/Cordova, Node, browser, operating system): Chrome 60, Windows 7

How to reproduce these conditions

Failing test unit, Plunkr, or JSFiddle demonstrating the problem

Steps to set up and reproduce
Have read a bit old issue #362 but I am raising here again with some info. For pagination, I need to use startAt with optional key combined with orderByChild.

To emulate the behavior that gets the next page content, I ran below code with some hard coded values found in my notes database and it gives me what I expected - two notes under 'Issues' group starting with the one with given key:

    const query = this.db.database.ref('notes')
      .orderByChild('group')
      .limitToFirst(2)
      .startAt('Issues', '-KqFzkJy-DCM7mmH3jo5');
    query.on('child_added', (snap) => {
      console.log(snap.val(), snap.key);
    });

But if run below code, I got nothing:

    this.notes = this.db.list(`notes`, {
      query: {
        orderByChild: 'group',
        equalTo: 'Issues',
        limitToFirst: 2,
        startAt: { value: 'Issues', key: '-KqFzkJy-DCM7mmH3jo5' } // need this feature..
      }
    });

If I comment out startAt line above, it gives me first two notes under 'Issues' group.

Sample data and security rules

<-- include/attach/link to some json sample data (or provide credentials to a sanitized, test Firebase project) -->

Debug output

** Errors in the JavaScript console **

** Output from firebase.database().enableLogging(true); **

** Screenshots **

Expected behavior

Get the same result that Firebase SDK gives.

Actual behavior

No console errors, no result.

@davideast
Copy link
Collaborator

@bob-lee I'm in support of this, but to be honest I don't have the time to implement it. However, if you'd like to send in the PR I'd be more than happy to provide guidance and review. Let me know if you're interested!

@bob-lee
Copy link
Contributor Author

bob-lee commented Aug 18, 2017

@davideast Absolutely I am in. Where can I start?

@bob-lee
Copy link
Contributor Author

bob-lee commented Aug 18, 2017

@davideast there was a PR #821 merged last Feb but that doesn't seem to help the situation. As a first step, I forked and tried npm run build on my machine which gives me following error..?:

C:\Users\Bob\Work\angularfire2 (master)
λ npm run build

> [email protected] build C:\Users\Bob\Work\angularfire2
> rm -rf dist && node tools/build.js

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: spawn node_modules/.bin/ngc ENOENT
    at exports._errnoException (util.js:1018:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
    at onErrorNT (internal/child_process.js:367:16)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)
    at Module.runMain (module.js:606:11)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:504:3

npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "build"
npm ERR! node v6.11.1
npm ERR! npm  v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build: `rm -rf dist && node tools/build.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script 'rm -rf dist && node tools/build.js'.

@bob-lee
Copy link
Contributor Author

bob-lee commented Aug 20, 2017

I realized I was mistakenly using equalTo in above angularfire2 code so once that line is commented out like below, I got the same result that Firebase SDK code gives:

    this.notes = this.db.list(`notes`, {
      query: {
        orderByChild: 'group',
        //equalTo: 'Issues',
        limitToFirst: 2,
        startAt: { value: 'Issues', key: '-KqFzkJy-DCM7mmH3jo5' }
      }
    });

So PR #821 was doing its job ok but now the result is not guaranteed to contain only notes under 'Issues' group due to a missing equalTo.

Just for test, I included equalTo in Firebase SDK code then it complains like:

Error: Query.startAt: Starting point was already set (by another call to startAt or equalTo).

This seems to be a fundamental limitation in Firebase , in other words, if I want a page that shows all notes with pagination, that's possible but if I want a page that shows only notes that belong to a particular group with pagination, that's not possible to do with current Firebase functionality. There is not much room to improve the situation in angularfire2 side I guess. Am I correct @davideast please?

BTW, I could run npm run build on my Windows machine after I replaced child_process with cross-spawn in tools/build.js:

//const { spawn } = require('child_process');
const { spawn } = require('cross-spawn'); // to build on Windows machine

@SpeedoPasanen
Copy link

SpeedoPasanen commented Aug 26, 2017

Ran into this limitation of Firebase myself and solved it by adding composite keys to everything. Let's say you'd have:

{ groupOrder: 'Issues 1111', someValue: '', .... }, { groupOrder: 'Issues 1112', someValue: '', ... }

Then you can:

query: {
    orderByChild: 'groupOrder',
    startAt: 'Issues', // or if you're paginating, let's say 'issues 1112'
    endAt: 'IssuesZ' // startAt and endAt eliminate the need for equalTo
    limitToFirst: pageSize
}

Got a cloud function triggered by a push to these lists, which adds the composite keys like groupName + ' ' + {new Date().getTime()}

Let's say you also have a relation to a user, just add a composite key userOrder: userKey + ' ' + timestamp and there ya go.

These what we might call limitations compared to SQL can be advantages, once you manage to forget all you know about SQL and start thinking Firebase way. It's what makes FB so freaking fast and scalable.

Sorry this got out of the scope of github issues. =) Huge thanks to @davideast for work like this to make it easier to learn this stuff: https://github.com/davideast/Querybase

@davideast
Copy link
Collaborator

@bob-lee Not a problem in the new API which allows you to formulate a query using a callback. Check out the new docs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants