Firebase Database Security Rules API

What’s up guys, Eze is here. I already did couple of posts about Firebase and how to use the Real-Time database and the storage with AngularJs in case you missed it you can check here. Today I want to talk about security rules. I’ve answered this question in StackOverflow and that motivated me to write this post.

Understanding Rules object

As almost everything in Firebase the rules for our database will be a JSON Object. We are going to use this object to define security, data structure and of course validations. As you can see below the structure of this object is quite simple. It has only one property called rules which will have the rules definitions.

{
"rules": {
"users": {
".read": "root.child(‘access_token’).child(auth.uid).exists()"
}
}
}

Rules types

Under the security rules we can define four different types. We can apply those types to the complete database as is in the example above or we can define every type at an specific path.

  • .read: This rule is a type of Security Rule which grants a client read access to a database location.
  • .write: This rule is a type of Security Rule which grants a client write access to a database location
  • .validate: This rule is used once a .write rule has granted access, to ensure that the data being written conforms to a specific standard
  • indexOf: This rule tells the database servers to index specific keys in your data to improve the performance of your queries

Rules variables

As you can imagine Firebase use an specific set of variables to perform the rule types that we defined before.

  • auth: This variable will contain the token payload in case the is an authenticated user.
    • provider : The authentication method used by the user.
    • uid: This will be the uid to the authenticated user.
    • token: This variable contains the contents of the Firebase Auth ID token.
  • $location: In this case the $ is used to reference in a generic way to the child within the path.
  • now: Contains the number of milliseconds since the Unix epoch according to the database servers.
  • root: It’s a RuleDataSnapshot to the current data at the root level. That means we can query others path to validate.
  • data: It’s a RuleDataSnapshot corresponding to the actual data in the path.
  • newData: It’s a RuleDataSnapshot corresponding with the data that will result if the write is allowed.

Rules methods and operators

To complete the types and variables Firebase offers us a series of method to apply over the variables that we will use within the types. Just to name a couple we can use the val() method to retrieve the value of the snapshot o child() to query the paths.

In the same way we can use most of the logical operators like === equals , !=== not equals, || or, ! not and so on.

Using all together

In the example below I defined a rule for the path users. Using the $user means that this rule is for every child under the path users with the id user. Then I defined the types so I started with .read, by assigned true means that everyone (even unauthenticated users) can read under this path. For .write path I access to the variable root to query the access_token path with a child that belongs to the authenticated user uid and then use the method exists to validate if there is data under this path. To finish I used the .validate type to validate the newData to write has the right structure.



</span><span class="pun">{
    "rules": {
       "users": {
          "$user": {
             ".read": true,
             ".write": "root.child('access_token').child(auth.uid).exists()",
             ".validate": "newData.hasChildren(['name', 'age'])"
         }
      }
   }
}

 

For a complete reference of Firebase use this link.

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and, as always, thank you for reading.

Firebase – Real-Time Database using Angular 2

What’s up guys, Eze is here. Those who follow me on Twitter (if you are not a follower you better do it now @skielo) already know I’ve been working on an app to show you how to use Firebase from an Angular 2 app. I have several post talking about Firebase and how to use almost all its functionalities from an AngularJS app, in case you missed it you can check it here. Today I want to show you how easy is to get up and running an Angular 2 app and connect it to Firebase. This will be the first out of a series of post  where we are going to find out more about those tools.

The skeleton of our app

I want to show you first how to create a new Angular 2 app from the scratch. To do that we will need to install in our machines the angular cli tool. The installation of this tool it’s really simple we just need run the following command npm install -g @angular/cli. Please be sure you have a node version higher than 4 because it’s a requirement for this tool to run.

This tool will provide us lots of functionalities that we are going to use during the development of our app but first we need to create the scaffolding of our app, by executing the following command ng new app_name the Angular cli will create a new Angular 2 app. We can see our app running by executing ng serve command.

ng_create.PNG

Adding Angular Fire 2 and Firebase to our project

We already have the basics of our project it’s time to add the reference to Angular Fire 2 and Firebase and we will do it by running the following command inside our project folder  npm install angularfire2 firebase –save. This command is going to install all the necessary files in our project. So now it’s time to dive into our app.module.ts in order to configure our Firebase project. First we need import AngularFireModule and then export the configuration we get from Firebase.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AngularFireModule } from 'angularfire2';

import { AppComponent } from './app.component';

export const firebaseConfig = {
apiKey: '',
authDomain: '',
databaseURL: '',
storageBucket: '',
messagingSenderId: ''
};

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AngularFireModule.initializeApp(firebaseConfig)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Creating a Database layer

Now we have configured Firebase to our project so it’s time to create our database layer in order to have access to our database. Again we are going to use Angular cli by typing ng generate service databaseservice. This time the command is going to generate a new service but you need to take care of something else which is the warning we got from the tool: “WARNING Service is generated but not provided, it must be provided to be used”. In order to provide this new service we need to include it in the AppComponent as I did below.

import { Component } from '@angular/core';
import { DatabaseService } from './core/database.service';

@Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: 'app.component.html',
providers: [DatabaseService]
})
export class AppComponent {

}

As you can see in the code above we use a great feature of Type Script that allows us to define a property in the constructor which means that Angular will automatically inject the right object for us.

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { AngularFire, FirebaseObjectObservable, AngularFireAuth } from 'angularfire2';

@Injectable()
export class DatabaseService {

constructor(private _af: AngularFire) {
}

createBattle(obj: Battle){
return this._af.database.list('/battles').push(obj);
}

And that’s it, after doing that we are ready to go. This AngularFire object will give us access to all Firebase functionality. In this example I’m using the database object in particular the list method. As you can see we need pass the path reference to this method and the return will be an FirebaseListObservable object that will let us work with our database.

If you want to see the full code working together I have a working example here. This example is an small version of the game battleship.

For a complete reference of Angular Fire 2 use this link.

For a complete reference of Firebase use this link

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and as always thank you for reading.

Firebase – Storage using Angularjs

What’s up guys, Eze is here. Yesterday we got an awesome post about Firebase and how to use the Real-Time database with AngularJs in case you missed it  here you go the link. Today I want to talk about another useful feature of Firebase: Storage an amazing tool that allows us to store and serve user-generated content, such as photos or videos. As they explained in their website:

Firebase Storage adds Google security to file uploads and downloads for your Firebase apps, regardless of network quality. You can use it to store images, audio, video, or other user-generated content.

Adding Firebase to your web app

Well if you read my previous post you already knows how to add Firebase reference to your website. If you didn’t yet go and read it first here.

Creating your data layer

As I did for the Real-Time database I’m going to create a data layer. To do that I’m going to create an AngularJs service to use as data layer. This service will be responsible to create our links to the Firebase store. As you can see below is quite similar to the one we use to connect to our Real-Time database.

 function storageService($http, $firebaseArray, $firebaseObject, $q) {
    var root = firebase.database().ref();
    var storageRef = firebase.storage().ref();

Now we have the reference so we can add a function to our service in order to upload the image.

 function upload(file, uid, fileName) {
    var deferred = $q.defer();
    var fileRef = storageRef.child(uid).child(fileName);
    var uploadTask = fileRef.put(file);

    uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
       function(snapshot) {
          var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
          console.log('Upload is ' + progress + '% done');
          switch (snapshot.state) {
             case firebase.storage.TaskState.PAUSED:
               console.log('Upload is paused');
               break;
             case firebase.storage.TaskState.RUNNING:
               console.log('Upload is running');
               break;
          }
      }, 
      function(error) {
         switch (error.code) {
            case 'storage/unauthorized':
                deferred.reject('User does not have permission to access the object.');
                break;
            case 'storage/canceled':
                deferred.reject('User canceled the upload.');
                break;
            case 'storage/unknown':
                deferred.reject(' Unknown error occurred, Please try later.');
                break;
          }
       }, function() {
             deferred.resolve(uploadTask.snapshot.downloadURL);
       });

    return deferred.promise;
 }

Again we use the function child to create the path, in my case I’m using the user uid as a root folder so I’ll group all files per user and then another child with the file name. At this point it’s important to highlight that I’m using the function child twice but we can do it in this way child(‘folder_name/file_name’) and will create the same structure.

Uploading the file

Once we get the reference we need to use the put function to upload the file. This file object can be a blob, a file or byte array and it returns a promise that allows us to trace the progress, catch errors and handle the success response which provides us a downloadURL property to get the public url of our document. Our storage structure looks like this:

storage

As you can see it’s really easy to get this storage up an running.  I have a working example in this link if you want to see the complete implementation. In this example I created an app that allows you to select different places around the world and upload an image that appears in a google maps.

For a complete reference of Firebase storage use this link.

For a complete reference of Angular Fire use this link.

For a complete reference of Firebase use this link

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and as always thank you for reading.

Firebase – Real time database using AngularJs

What’s up guys, Eze is here. Today I want to talk you about Firebase a powerful Google suitcase that provides a bunch of tools such as storage, cloud messaging, hosting and a real time database that can be accessed via web, ios or android app.

Adding Firebase to your web app

Today I’m going to explain how to insert a Json object into the real time database and restore that value using AngularJs. You only need to reference AngularJs, Firebase and AngularFire libraries in your  project.

<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>

<!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.6.4/firebase.js"></script>

<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/2.2.0/angularfire.min.js"></script>

Then we need to add Firebase configuration in our index.html. To do that we need to go into the Firebase console and get the initialization code as you can see in the image below.

initcode

Creating your data layer

I will create an AngularJs service to use as data layer. This service will be responsible to create our links to the Firebase real time database. Here we are going to use two important functions in the firebase library. The first one is ref() from the database() object. This function returns a direct link to the root structure of our documental database. The second function is child() which allow us to create child reference to this root structure.

 function firebaseDataService() {
    var root = firebase.database().ref();

    var service = {
       root: root,
       requests: root.child('requests')
    };

    return service;
 }

In the example above we have a path to the root structure and a child of this path call requests.

Using AngularFire to manipulate the rreference

Now we have a service to get a link to our database reference so now we are going to use angular fire to create an object with access to our database.

function getRequestsByUser(uid) {
if (!requests) {
requests = $firebaseArray(firebaseDataService.requests.child(uid).child('userRequests'));
}
return requests;
}

In the example above we use $firebaseArray function to create an object, the parameter this function uses is a path reference to Firebase. This object is now linked to our database which means that every time you put or remove an object from this array is going to affect our database in real time. We can use the function $add or $remove to manipulate our database. Our database looks like this.

db

And that’s it, after doing that we are ready to go. I have a working example in this link if you want to see the complete implementation. In this example I created an app that gives you the current time in different places around the world.

For a complete reference of Angular Fire use this link.

For a complete reference of Firebase use this link

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and as always thank you for reading.