1

I am new in Firebase. I have problem while executing query:

new Firebase("https://blazing-fire-2739.firebaseio.com/users")
        .startAt($scope.user.email) //karank@ocodewire.com
        .endAt($scope.user.email)
        .once('value', function(snap) {
           console.log('accounts matching email address', snap.val())
        });

This shows me null.

In Firebase:

users
   -JxFNEu31LJ0Efy8PnX5
      email: karank@ocodewire.com
      firstname:karan 
      lastname: sofat

Please Help

2 Answers2

2

In the documentations for Query.startAt() and Query.endAt(), under 'Arguments', you will see that the first argument, value, is:

The value to start [or end] at. The argument type depends on which orderBy*() function was used in this query. Specify a value that matches the orderBy*() type. When used in combination with orderByKey(), the value must be a string.

The Querying Data section of the Web Guide says,

With Firebase database queries, we can selectively retrieve data based on various factors. To construct a query in your database, you start by specifying how you want your data to be ordered using one of the ordering functions: orderByChild(), orderByKey(), orderByValue(), or orderByPriority(). You can then combine these with five other methods to conduct complex queries: limitToFirst(), limitToLast(), startAt(), endAt(), and equalTo().

  • If the user objects have a priority, and an orderBy is not specified for the Query, the query will sort by priorities and startAt/endAt by indices will work. You can use .setPriority() or .setWithPriority().
  • If the user objects do not have a priority set, and the Query has no orderBy*(), snapshot.val() will be null.

For your query, if the user objects do not have priorities set, sorting by the email child will make startAt/endAt work, like so:

new Firebase("https://blazing-fire-2739.firebaseio.com/users")
    .orderByChild('email')
    .startAt($scope.user.email)
    .endAt($scope.user.email)
    .once('value', function(snap) {
       console.log('accounts matching email address', snap.val())
    });

Here is a working plnkr example of this query.


However, as Kato pointed out in the comments,

"As a general recommendation, orderByChild() supersedes priorities and should be preferred. Priorities will eventually be phased out in favor of child fields."

Since your goal is to locate a single specific user by her email address and since there should be only one user with a given email child value, you can,

  • Order the Query object for /users by the "email" child key;
  • Query for the user object for which the email child is equalTo(<email>).

For example:

var usersRef = new Firebase("https://blazing-fire-2739.firebaseio.com/users");
userRef.orderByChild("email").equalTo($scope.user.email).once("value", function(snapshot) {
  if(snapshot.exists()){
    console.log(snapshot.val());
  }
});

And here is a working plnkr example of this second query.

For more information, check out the documentation for Query.equalTo() and Query.orderByChild().

Important side-note: when ordering by a child key, if you know what the indices for your query will be, "you can define them via the .indexOn rule in your Security and Firebase Rules for better performance." Check out the Indexing Data documentation for more info.


It might be helpful to read over the Retrieving Data Guide.

To inspect your Firebase data in the browser and see objects' priorities, you can use Vulcan -- an awesome Google Chrome extension. This is what Vulcan looks like in the Chrome DevTools:

vulcan
(source: firebase.com)


Hope this helps!

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
sbolel
  • 3,486
  • 28
  • 45
  • 1
    Great work! Covers most of the details. As a general recommendation, `orderByChild()` supersedes priorities and should be preferred. Priorities will eventually be phased out in favor of child fields. – Kato Aug 24 '15 at 21:07
  • Thanks @Kato, that is great to know. – sbolel Aug 24 '15 at 22:13
  • Kind of curious how with equalTo, snap.key() doesn't actually return the key of the object returned... see plunkr: http://plnkr.co/edit/BbWn3DpNjbXtx8pgH8j8?p=preview – morgs32 Sep 30 '15 at 20:52
  • Looks like you can't use "value", but instead "child_added". I suppose that makes a little sense. – morgs32 Sep 30 '15 at 20:56
0

.startAt and endAt doesn't accept a string, it accept a number where to start/end at. So you would have to change to

new Firebase("https://blazing-fire-2739.firebaseio.com/users")
  .startAt(1)
  .endAt(50)
  .once('value', function(snap) {
    console.log('accounts matching email address', snap.val());
});

Or just leave out the endAt() altogether.

Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175
  • It is important to note that this will not work unless the user objects are set with a priority. This [answer](http://stackoverflow.com/a/24102307/1526037) shows the ordering rules. You will need [`.setPriority()`](https://www.firebase.com/docs/web/api/firebase/setpriority.html) or [`.setWithPriority()`](https://www.firebase.com/docs/web/api/firebase/setwithpriority.html) – sbolel Aug 22 '15 at 09:24
  • You can see that this does not work in [this plnkr](http://plnkr.co/edit/oTIqlEwzovH8da2soVqN?p=preview) – sbolel Aug 22 '15 at 09:41