By PushTable.com, serverless CMS powered by Firebase

This guide is written by the team at PushTable, we have worked with the Firebase API extensively through our development process. We have compiled a set of useful tips and queries that has served us well.

Practical Overview of Firebase Queries

We will just look at the Admin SDK in this guide, the functionalities across various SDKs are generally the same. The most notable difference is that the REST API supports shallow queries, and advanced feature that is not support anywhere else. Additionally, the REST API only supports orderByChild if the valued is indexed.

In this guide, we'll include some practical tips to querying Firebase data. The official guide can be found at https://firebase.google.com/docs/database/admin/retrieve-data and the full API reference is located at https://firebase.google.com/docs/reference/admin/node/admin.database.Query

Queries

Because Firebase is designed to be highly scalable it has a slightly different syntax that traditional relational database. However, it still provides all the key capabilities that you would require to perform filter, sort and pagination operations.

In Firebase, there are two type of operators, order operators and filter operators.

Order Operators
orderByKey(); orderByChild(); orderByValue(); orderByPriority();

// example
var ref = admin.database().ref("users");
ref.orderByChild('name').once("value", function(snapshot) {
  console.log(snapshot.val());
});

Which order operators to use will depend on the nature of your data.

  • orderByKey can be use on any data type. If the data is keys are set with firebase.push(), the unique key generated by push() are ordered by the current time, so the resulting list of items will be chronologically sorted.
  • orderByValue is useful when the data is an array of values
  • orderByChild is useful when the data is a collection of objects.
  • orderByPriority can be used when you want to set a custom order in a collection
Filter Operators

The filter operators enables range and equality queries.

limitToFirst(); limitToLast(); startAt(); endAt(); equalTo();

// example
var ref = admin.database().ref("users");
ref.orderByChild('subscribed').equalTo(true).once("value", function(snapshot) {
  console.log(snapshot.val());
});

Inequality

To perform >= or <= queries, we can simply use startAt and endAt commands. Firebase currently does not support non-inclusive queries so to implement greater than or less than queries, user will need to filter out the value from the result.

// example >= query: greater than or equal to
ref.orderByChild('login_count').startAt(1).once("value", function(snapshot) {
  console.log(snapshot.val());
})

// example <= query: less than or equal to
ref.orderByChild('friends').endAt(1).once("value", function(snapshot) {
  console.log(snapshot.val());
})

// example < query: less than
ref.orderByChild('friends').endAt(1).once("value", function(snapshot) {
  console.log(snapshot.val().filter(el.friends !== 1));
})
Equality Query

To write an equality query, simply use the equalTo() command.

ref.orderByChild('name').equalTo('John Wick').once("value", function(snapshot) {
  console.log(snapshot.val());
})

Existence

Is NULL query

The key to mastering how to to build Firebase queries is to know how data is order in Firebase.

ref.orderByChild('profile_picture').equalTo(null)

// Alternatively, to demonstrate how the data order works, we can query for the following because null is in the order
ref.orderByChild('profile_picture').endAt(null)
Is NOT NULL query

While Firebase does not support a not equal to command, you can use the data sort order to select valu

// Because the data sort order is null, false, true, strings (lexical order), objects, 
ref.orderByChild('profile_picture').startAt(false)

Similarly, you can use the startAt, endAt operators and the data order to query for different sets of data types. Note that startAt and endAt are inclusive operators.

// query: IS Boolean
ref.orderByChild('name').startAt(false).endAt(true)
// query: IS string
ref.orderByChild('name').startAt('').endAt('~')

// query: IS numeric, however in this case it'll include values == '', which you can filtered on the clientside
ref.orderByChild('name').startAt(0).endAt('')
// query: IS object, again this case includes the value '~' which needs to be removed from the result 
ref.orderByChild('name').startAt('~')

// query: all users with name that starts with 'a', note that '~' is the last printable ASCII character, if you data includes unicode it will not include those. Also it will not include values after a~ such as a~*
ref.orderByChild('name').startAt("a").endAt("a~")

// A sample dataset of different data types
ref.set({
  1: "", // name === null
  2: {"name": "a"},
  3: {"name": "b"},
  4: {"name": "!"},
  5: {"name": "~"},
  6: {"name": 0},
  7: {"name": false},
  8: {"name": true},
  9: {"name": "az"},
  10: {"name": " "},
  11: {"name": "\n"},
  12: {"name": {"key": ""}},
  13: {"name": ""}
})

(sources 1,2, ascii table)

Pagination

Pagination works slightly differently in Firebase. In order to achieve a scalable performance, it is designed to paginate by a use of a cursor instead of the typical offset and per page parameters. To fetch the next page of the content the user needs to pass in the last key in the current view and use that as the starting cursor for the next page. Conversely to fetch the previous page the user needs to pass in the first key of the current view to use as the ending cursor.

next page
var lastKey = '-KmDxW6geBlVa7OvHsLb'
ref.orderByKey().startAt(lastKey).limitToFirst(10)
previous page
var firstKey = '-KmAF8EXDvOSuqi-43Dj'
ref.orderByKey().endAt(firstKey).limitToLast(10)

Sort Order

https://firebase.google.com/docs/database/admin/retrieve-data#section-ordered-data

orderByChild

When usingorderByChild(), data that contains the specified child key will be ordered as follows:

  1. Children with a null value for the specified child key come first.
  2. Children with a value of false or the specified child key come next. If multiple children have a value of false, they are sorted lexicographically by key.
  3. Children with a value of true for the specified child key come next. If multiple children have a value of true, they are sorted lexicographically by key.
  4. Children with a numeric value come next, sorted in ascending order. If multiple children have the same numerical value for the specified child node, they are sorted by key.
  5. Strings come after numbers, and are sorted lexicographically in ascending order. If multiple children have the same value for the specified child node, they are ordered lexicographically by key.
  6. Objects come last, and sorted lexicographically by key in ascending order.
orderByKey

When usingorderByKey()to sort your data, data will be returned in ascending order by key as follows. Keep in mind that keys can only be strings.

  1. Children with a key that can be parsed as a 32-bit integer come first, sorted in ascending order.
  2. Children with a string value as their key come next, sorted lexicographically in ascending order.
orderByValue

When using orderByValue(), children will be ordered by their value. The ordering criteria is the same as in orderByChild(), except the value of the node is used instead of the value of a specified child key.

Indexing

When using orderByChild the value should be indexed. This can done by setting the .indexOn in the database rules. Note that this is not required when using the Firebase SDK during development as it will automatically fetch the entire collection and sort it according to the query in the client. Indexing is highly recommended for large datasets in production and is required when using the REST API.

Reverse order

To get items in reverse order users can use the endAt() and limitToLast() command

ref.orderByChild('name').endAt('~').limitToLast(10).once('value', function(snapshot) {
    // we will get last 10 users ordered by user.name
    // Note that the results will not response in reverse order so you will need to sort the results on the clientside
    console.log(snapshot.val())
});

Firebase as a CMS Database

Firebase is a highly popular mobile and web development platform by Google. It can really enable developers to build high quality scalable applications much faster. It's most notable feature is its real-time, database with js client support. The Firebase JS Client enables developers to go serverless and directly and securely allow users to access the database from the browser. This significantly simplify the development process.

PushTable is a content management system (CMS) built on top of the FIrebase real-time database. It allows content editors to use a intuitive and friendly interface to access the data while developers can continue to use the Firebase API that they have come to love. This document summarizes features from the official Firebase documentation and highlights how it can used in a typical headless CMS workflow.

Firebase as a CMS Database

With PushTable content management system and the Firebase API, businesses can significantly simplify their development process. Data in stored in Firebase DB can easily connect to multiple platforms and used to build static web pages, drive mobile application data, configure settings for their single page applications and more.

One key advantage of using a CMS powered by Firebase is the ability to build applications using a serverless architecture. The combination of Firebase's ability to be queried directly from the browser, Firebase Cloud Functions and Firebase Web Hosting allows developers to easily build their application without having to worry about maintaining server environments.

A static page or flat file website is one where the content delivered to the user is exactly what is stored. In contrast to dynamic web pages where the content is generated by a web server. However, a static site does not mean that it is less capable than a dynamic site. A static site can still render dynamic content but it does so on the browser using javascript instead of using a server-side scripting language.

Static sites are fast becoming popular again amongst developers. Building a webpage as a static site means that you don't have to use a server. If you can build a website or application without the use of a server It allows for much better performance and security. It enables you distribute your website across a global CDN and can ensure that anyone in the world can access your content quickly. Additionally if you are an agency or a company with many websites it saves a lot of maintenance effort to not have to worry about all the different server environments.

Static Site Hosting with Firebase

Firebase offers a hosting solution for static websites and enables developers to quickly and easily deploy web apps and static content to a global content-delivery network (CDN). It offers a generous free storage capacity, support custom domain and rewrite rules and will automatically generate an SSL certificate for you.

Simply download the command line tool, go to your project directory and run:

firebase init

Now you can add your files that you want to deploy and run:

firebase deploy

Instantly you'll have live website running. Please see the full documentation to customize hosting behavior.

results matching ""

    No results matching ""