---
title: "Firebase: Now with more querying!"
description: "Firebase: Now with more querying!"
published: "2014-11-04"
last_updated: "2014-11-04"
authors:
  - "Michael Lehenbauer (Core Developer)"
categories:
  - "Launch"
  - "Realtime Database"
canonical_url: "https://firebase.blog/posts/2014/11/firebase-now-with-more-querying"
---

# Firebase: Now with more querying!

*Published November 4, 2014 by Michael Lehenbauer (Core Developer)*

---
Today we're launching enhanced query support across our [iOS](https://www.firebase.com/docs/ios/), [Android](https://www.firebase.com/docs/android/), and [Web](https://www.firebase.com/docs/web/) clients, and the Firebase [REST API](https://www.firebase.com/docs/rest/)! You can now query your data by any child key in Firebase. Querying has been a frequently requested feature and we’ve made great strides based on developer feedback since our beta release last month.

This release dramatically improves the way you can query your data in Firebase. With our new querying methods you can order and retrieve your data using a child key, by key name, or by priority. Our existing priorities-based ordering will continue to work, but I encourage you to try out the new queries features as it is much more flexible.

A basic Firebase query starts with one of our orderBy functions: `orderByChild()`, `orderByKey()` or `orderByPriority()`. You can then combine these with five other methods to conduct complex queries: `limitToFirst()`, `limitToLast()`, `startAt()`, `endAt()`, and `equalTo()`. Since all of us at Firebase agree that dinosaurs are pretty cool, we’ll use [this sample firebase](https://dinosaur-facts.firebaseio.com/) of dinosaur facts to demonstrate how you can write complex, realtime queries. To start, we can use `orderByChild()` to retrieve dinosaurs ordered by height:

```js
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("height").on("child_added", function(snapshot) {
  console.log(snapshot.key() + " was " + snapshot.val().height + " meters tall");
});
```

```js
Firebase *ref = [[Firebase alloc] initWithUrl:@"https://dinosaur-facts.firebaseio.com/dinosaurs"];
[[ref queryOrderedByChild:@"height"]
    observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {

    NSLog(@"%@ was %@ meters tall", snapshot.key, snapshot.value[@"height"]);
}];
```

```java
Firebase ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
Query queryRef = ref.orderByChild("height");

postsQuery.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot snapshot, String previousChild) {
        System.out.println(snapshot.getKey() + " was " + snapshot.getValue().get("height") + " meters tall");
    }
    // ....
});
```

```js
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"'
```

We can also use our limit methods to return the two heaviest dinosaurs in our Firebase:

```js
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("weight").limitToLast(2).on("child_added", function(snapshot) {
  console.log(snapshot.key());
});
```

```js
Firebase *ref = [[Firebase alloc] initWithUrl:@"https://dinosaur-facts.firebaseio.com/dinosaurs"];
[[[ref queryOrderedByChild:@"weight"] queryLimitedToLast:2]
    observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {

    NSLog(@"%@", snapshot.key);
}];
```

```java
Firebase ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
Query queryRef = ref.orderByChild("weight").limitToLast(2);

queryRef.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot snapshot, String previousChild) {
        System.out.println(snapshot.getKey());
    }
    // ....
});
```

```js
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="weight"&limitToLast=2'
```

Adding it all together with our range methods (`startAt()` and `endAt()`) we can find all dinosaurs that are at least three meters tall:

```js
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("height").startAt(3).on("child_added", function(snapshot) {
  console.log(snapshot.key())
});
```

```js
Firebase *ref = [[Firebase alloc] initWithUrl:@"https://dinosaur-facts.firebaseio.com/dinosaurs"];
[[[ref queryOrderedByChild:@"height"] queryStartingAt:@3]
    observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {

    NSLog(@"%@", snapshot.key);
}];
```

```java
Firebase ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
Query queryRef = ref.orderByChild("height").startAt(3);

queryRef.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot snapshot, String previousChild) {
        System.out.println(snapshot.getKey());
    }
    // ....
});
```

```js
curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3'
```

The best part is that all these queries will update in realtime as the data changes in your Firebase. There’s more I haven’t covered, so be sure to read the documentation for the [iOS](https://www.firebase.com/docs/ios/guide/retrieving-data.html#section-queries), [Android](https://www.firebase.com/docs/android/guide/retrieving-data.html#section-queries) or [Web](https://www.firebase.com/docs/web/guide/retrieving-data.html#section-queries) clients or the [REST API](https://www.firebase.com/docs/rest/guide/retrieving-data.html#section-queries) to learn about all the new features.

With querying, we’re also introducing a new [indexOn](https://www.firebase.com/docs/security/guide/indexing-data.html) rule type to the Firebase Security and Rules language. You can use indexOn to tell your Firebase which child keys your app uses in queries. A node's key and and priority are indexed automatically, so there is no need to index them explicitly. Using indexOn is optional and can be left off for prototyping, but it will dramatically improve performance so you'll want to add it once you've figured out the indexes your queries will use.

### There's more coming!
While this represents a big step forward in terms of our querying capabilities it also lays the groundwork for even more improvements. We have a number of exciting features in the pipeline for our SDKs, including more queries improvements. And as always, we'd welcome your feedback on what you'd like to see next.

Let us know what you think in our [Google Group](https://groups.google.com/forum/#!forum/firebase-talk) or on [Twitter](https://twitter.com/firebase), and send any suggestions to [firebase-support@google.com](mailto:firebase-support@google.com).
