Book Image

Serverless Web Applications with React and Firebase

By : Harmeet Singh, Mayur Tanna
Book Image

Serverless Web Applications with React and Firebase

By: Harmeet Singh, Mayur Tanna

Overview of this book

ReactJS is a wonderful framework for UI development. Firebase as a backend with React is a great choice as it is easy, powerful, and provides great developer experience. It removes a lot of boilerplate code from your app and allows you to focus on your app to get it out quickly to users. Firebase with React is also a good choice for Most Viable Product (MVP) development. This book provides more practical insights rather than just theoretical concepts and includes basic to advanced examples – from hello world to a real-time seat booking app and Helpdesk application This book will cover the essentials of Firebase and React.js and will take you on a fast-paced journey through building real-time applications with Firebase features such as Cloud Storage, Cloud Function, Hosting and the Realtime Database. We will learn how to secure our application by using Firebase authentication and database security rules. We will leverage the power of Redux to organize data in the front-end, since Redux attempts to make state mutations predictable by imposing certain restrictions on how and when updates can happen. Towards the end of the book you will have improved your React skills by realizing the potential of Firebase to create real-time serverless web applications.
Table of Contents (16 chapters)
Title Page
Copyright and Credits
Packt Upsell
Contributors
Preface
Free Chapter
1
Getting Started with Firebase and React
Index

Firebase


The Firebase platform helps you develop high-quality apps and focus on your users.

Firebase is a mobile and web application development platform backed by Google. It is a one-stop solution for all your needs to develop high-quality mobile and web applications. It includes various products, such as Realtime Database, Crash reporting, Cloud Firestore, Cloud Storage, Cloud functions, Authentication, Hosting, Test lab for Android, and Performance monitoring for iOS, which can be used to develop and test Realtime applications by focusing on the user's needs, rather than the technical complexities.

It also includes products such as Cloud Messaging, Google Analytics, Dynamic Links, Remote Config, Invites, App Indexing, AdMob, and AdWords that help you grow user base and also increase the engagement of your audience.

Firebase provides multiple Firebase services. We can access each service with the Firebase namespace:

  • firebase.auth() - Authentication
  • firebase.storage() - Cloud Storage
  • firebase.database() - Realtime Database
  • firebase.firestore() - Cloud Firestore

We'll cover all the preceding services in the upcoming chapters. In this chapter, we will go through the preceding products/services briefly to get a basic understanding of all features of the Firebase platform. In the upcoming chapters, we will explore web-related products  which can integrate with React platform, in more detail.

Here's the list of topics that we'll cover in this section:

  • Introduction to Firebase and its features
  • List of Firebase Features and how we can use it
  • Cloud Firestore
  • Firebase project setup with JavaScript
  • Sample application "Hello World" with Firebase and JavaScript

As you can see, Firebase offers two types of Cloud Database and Realtime Database, and both support real-time data syncing. We can use both of them in the same application or project. Okay, let's go into detail and learn more about them.

Realtime Database

For any Realtime application, we need a Realtime Database. The Firebase Realtime Database is a cloud-hosted NoSQL database that synchronizes the data in Realtime to every connected client. Instead of a typical request-response model, the Firebase database uses the synchronization mechanism that synchronizes the data to all the connected devices within milliseconds. Another key capability is its offline feature. The Firebase SDK persists the data on the disk; so, even if a user loses their internet connection, the app remains responsive. It automatically synchronizes the data once the connection is reestablished. It is supported by iOS, Android, Web, C++, and Unity platforms. We will cover this in detail in the upcoming chapters.

Note

Firebase Realtime Database can scale around 100,000 concurrent connections and 1,000 writes/second in a single database.

The following screenshot shows the list of features on the left, which are available in Firebase, and we have selected the Realtime Database in the database section. In that section, we have four tabs available:

  • DATA
  • RULES
  • BACKUPS
  • USAGE

Database rules

Firebase database rules are the only way to secure the data. Firebase provides flexibility and expression-based rules language with JavaScript-like syntax to developers to define how your data should be structured, how it should be indexed, and when the user can read and write the data. You can also combine authentication services with this to define who has access to what data and protect your users from unauthorized access. To validate the data, we need to add a rule separately using .validate in the rules.

Consider this example:

{
"rules": {
".write": true,
"ticket": {
// a valid ticket must have attributes "email" and "status"
".validate": "newData.hasChildren(['email', 'status'])",
"status": {
// the value of "status" must be a string and length greater then 0 and less then 10
".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 10"
},
"email": {
// the value of "email" must valid with "@"
".validate": "newData.val().contains('@')"
}
}
}
}

Here are some other sample blocks of code for applying rules in the Rules tab:

Default: Rule configuration for authentication:

{
 "rules": {
 ".read": "auth != null",
 ".write": "auth != null"
 }}

Public: These rules give full access to everyone, even people who are not users of your app. They give read and write access to your database:

{
 "rules": {
 ".read": true,
 ".write": true
 }}

User: These rules authorize access to a node matching the user's ID from the Firebase authentication token:

{
 "rules": {
   "users": {
       "$uid": {
             ".read": "$uid === auth.uid",
             ".write": "$uid === auth.uid"
         }
       }
    }
}

Private: These rule configs don't allow anyone to read and write to a database:

{
 "rules": {
    ".read": false,
    ".write": false
  }
}

Note

We can also use REST API with Firebase Secret code to write and update Rules for your Firebase app by making a PUT request to the /.settings/rules.json path and it will overwrite the existing rules. Take, for example, curl -X PUT -d '{ "rules": { ".read": true } }''https://docs-examples.firebaseio.com/.settings/rules.json?auth=FIREBASE_SECRET'.

Backups

Firebase allows us to save the daily backup of our database, but that is only available in the Blaze plan. It also applies the security rules automatically to secure your data.

Usage

Firebase allows seeing the usage of the database with the help of an analytical chart. It shows us the connections, storage, downloads, and load in Realtime on our firebase database:

Cloud Firestore

Cloud Firestore is also a cloud-hosted, NoSQL database. You might be thinking that we already have Realtime Database, which is also a NoSQL database, so why do we need Firestore? The answer to this question is that Firestore can be considered as an advanced version of Realtime Database that provides live synchronization and offline support along with efficient data queries. It scales globally and lets you focus on developing apps instead of worrying about server management. It can be used with Android, iOS, and web platforms.

We can use both databases within the same Firebase application or project. Both are NoSQL databases, can store the same types of data, and have client libraries that work in a similar manner.

If you want to try out Cloud Firestore while it's in beta, use our guide to get started:

Once we select the database, it prompts you to apply the security rules before creating the database.

Security rules

Before creating a database and collection in Cloud Firestore, it prompts you to apply the security rules for our database.

Take a look at the following screenshot:

Here are some code example of Firestore rules:

Public:

service cloud.firestore {
    match /databases/{database}/documents {
           match /{document=**} {
           allow read, write;
        }
    }
}

Users:

service cloud.firestore {
    match /databases/{database}/documents {
        match /users/{userId} {
           allow read, write: if request.auth.uid == userId;
        }
    }
}

Private:

service cloud.firestore {
    match /databases/{database}/documents {
       match /{document=**} {
          allow read, write: if false;
       }
    }
}

Difference between Realtime Database and Cloud Firestore

We have seen that both Realtime Database and Cloud Firestore are NoSQL Databases with Realtime capabilities of syncing the data. So, let's see the difference between both of them based on the features.

Data model

Both databases are cloud-hosted, NoSQL databases, but the data model of both databases is different:

Realtime Database

Cloud Firestore

  • Simple data is very easy to store.
  • Complex, hierarchical data is harder to organize at scale.
  • Simple data is easy to store in documents, which are very similar to JSON.
  • Complex and hierarchical data is easier to organize at scale, using subcollections within documents.
  • Requires less denormalization and data flattening.

Real-time and offline support

Both have mobile-first, Realtime SDKs, and both support local data storage for offline-ready apps:

Realtime Database

Cloud Firestore

Offline support for mobile clients on iOS and Android only.

Offline support for iOS, Android, and web clients.

Querying

Retrieve, sort, and filter data from either database through queries:

Realtime Database

Cloud Firestore

Deep queries with limited sorting and filtering functionality:

  • You can only sort or filter on a property, not sort and filter on a property, in a single query.
  • Queries are deep by default. They always return the entire subtree.

Indexed queries with compound sorting and filtering:

  • You can chain filters and combine filtering and sort on a property in a single query.
  • Write shallow queries for sub collections; you can query subcollections within a document instead of an entire collection, or even an entire document.
  • Queries are indexed by default. Query performance is proportional to the size of your result set, not your dataset.

Reliability and performance

When we choose the database for our project, then reliability and performance are the most important parts that come to our mind:

Realtime Database

Cloud Firestore

Realtime Database is a mature product:

  • Stability you'd expect from a battle-tested, tried-and-true product.
  • Very low latency, so it's a great option for frequent state-syncing.
  • Databases are limited to zonal availability in a single region.

Cloud Firestore is currently in beta:

  • Stability in a beta product is not always the same as that of a fully launched product.
  • Houses your data across multiple data centers in distinct regions, ensuring global scalability, and strong reliability.
  • When Cloud Firestore graduates from beta, it will have stronger reliability than Realtime Database.

Scalability

When we develop a large-scale application, we must know how much we can scale our database:

Realtime Database

Cloud Firestore

Scaling requires sharding:

Scale to around 100,000 concurrent connections and 1,000 writes/second in a single database. Scaling beyond that requires sharing your data across multiple databases.

Scaling will be automatic:

Scales completely automatically (after beta), which means that you don't need to share your data across multiple instances.

Security

As per the security concern, every database has a different way of securing data from unauthorized users:

Sourcehttps://firebase.google.com/docs/firestore/rtdb-vs-firestore?authuser=0.

Realtime Database

Cloud Firestore

Cascading rules that require separate validation.

  • Firebase Database Rules are the only security option.
  • Read and write rules cascade.
  • You need to validate data separately using .validate in the rule.

Simpler, more powerful security for mobile, web, and server SDKs.

  • Mobile and web SDKs use Cloud Firestore Security Rules, and server SDKs use Identity and Access Management (IAM).
  • Rules don't cascade unless you use a wildcard.
  • Data validation happens automatically.
  • Rules can constrain queries; if a query's results might contain data the user doesn't have access to, the entire query fails.

Note

As of now, Cloud Firestore is available in beta version; so, in this book, we are only focusing on Realtime Database.

Crash reporting

Crash reporting services help you diagnose problems in your Android and iOS mobile apps. It produces detailed reports of bugs and crashes and also sends them to the configured email address for quick notifications of the problems. It also provides a rich dashboard where you can monitor the overall health of your apps.

Authentication

Firebase Authentication provides a simple and secure solution to manage user authentication for your mobile and web apps. It offers multiple methods to authenticate, including traditional form-based authentication using email and password, third-party providers such as Facebook or Twitter, and using your existing account system directly.

FirebaseUI authentication for web

Firebase UI is completely open source and easily customizes to fit in with your app that includes some set of libraries. It allows you to quickly connect UI elements to the Firebase database for data storage, allowing views to be updated in Realtime, and it also provides the simple interfaces for common tasks such as displaying lists or collections of items.

FirebaseUI Auth is a recommended way to add authentication in Firebase app, or we can do it manually with Firebase Authentication SDK. It allows users to add a complete UI flow for signing in with email and passwords, phone numbers, and with most popular identity providers, including Google and Facebook Login.

FirebaseUI is available at https://opensource.google.com/projects/firebaseui.

We will explore more about Authentication in detail in the upcoming chapters.

Cloud Functions

Cloud Functions allow you to have serverless apps; you can run your custom application backend logic without a server. Your custom functions can be executed on specific events that can be emitted by integrating the following Firebase products:

  • Cloud Firestore triggers
  • Realtime Database triggers
  • Firebase Authentication triggers
  • Google Analytics for Firebase triggers
  • Cloud Storage triggers
  • Cloud Pub/Sub triggers
  • HTTP Triggers

How does it work?

Once you write and deploy a function, Google's servers start listening to those functions immediately, that is listening for events and running the function when it gets triggered. As the load of your app increases or decreases, it responds by rapidly scaling the number of virtual server instances needed to run your function faster. If the function is deleted, idle, or updated by you, then instances are cleaned up and replaced by new instances. In the case of deletion, it also removes the connection between functions and the event provider.

Given here are the events that are supported by Cloud Functions:

  • onWrite(): It triggers when data is created, destroyed, or changed in the Realtime Database
  • onCreate(): It triggers when new data is created in the Realtime Database
  • onUpdate(): It triggers when data is updated in the Realtime Database
  • onDelete(): It triggers when data is deleted from the Realtime Database

Here's a code sample of the cloud function makeUppercase:

exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
 .onWrite(event => {
 // Grab the current value of what was written to the Realtime Database.
 const original = event.data.val();
 console.log('Uppercasing', event.params.pushId, original);
 const uppercase = original.toUpperCase();
 // You must return a Promise when performing asynchronous tasks inside a Functions such as
 // writing to the Firebase Realtime Database.
 // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
 return event.data.ref.parent.child('uppercase').set(uppercase);
 });

Note

After you write the cloud function, we can also test and monitor our functions.

Cloud Storage

Any mobile or web app will need a storage space that stores user-generated content such as documents, photos, or videos in a secure manner and scales well. Cloud Storage is designed with the same requirement in mind and helps you easily store and serve user-generated content. It provides a robust streaming mechanism for a best end-user experience.

Here's how we can configure Firebase Cloud Storage:

// Configuration for your app
 // TODO: Replace with your project's config object
 var config = {
 apiKey: '<your-api-key>',
 authDomain: '<your-auth-domain>',
 databaseURL: '<your-database-url>',
 storageBucket: '<your-storage-bucket>'
 };
 firebase.initializeApp(config);
  // Get a reference to the storage service
 var storage = firebase.storage();
// Points to the root reference
var storageRef = storage.ref();

// Points to 'images'
var imagesRef = storageRef.child('images');

// Points to 'images/sprite.jpg'
// Note that you can use variables to create child values
var fileName ='sprite.jpg';
var spaceRef = imagesRef.child(fileName);

// File path is 'images/sprite.jpg'
var path = spaceRef.fullPath

// File name is 'sprite.jpg'
var name = spaceRef.name

// Points to 'images'
var imagesRef = spaceRef.parent;

Note

The total length of reference.fullPath must be between 1 and 1,024 bytes, with no Carriage Return or Line Feed characters. Avoid using #, [, ], *, or ?, as these do not work well with other tools such as Firebase Realtime Database.

Hosting

Firebase provides a hosting service where you can easily deploy your web apps and static content with a simple command. Your web content will be deployed on a global delivery network (GDN), so it will be delivered fast regardless of end-user location. It provides a free SSL for your domain to serve the content over a secure connection. It also provides full versioning and releases management with one-click rollbacks.

Test lab for Android

We test our Android app with a variety of devices running on different Android API versions to ensure that the end user can use our app with any Android device without any issues. However, it is not always possible to make all the different devices available to the testing team. To overcome such problems, we can use Test Lab, which provides cloudhosted infrastructure to test the apps with a variety of devices. It also makes it easy to collect test results with logs, videos, and screenshots. It also tests your app automatically to identify any possible crashes.

Performance Monitoring

Firebase Performance Monitoring is specifically designed for iOS apps' performance testing. You can easily identify the performance bottlenecks of your app with performance traces. It also provides an automated environment to monitor HTTP requests, which helps identify network issues. Performance traces and network data gives better insights on how your app is performing.

The following category of products is used in terms of increasing your user base and also engaging them in a better way.

Google Analytics

Google Analytics is a very well-known product and I think no developer needs its introduction. Google Analytics for Firebase is a free analytics solution to measure the user engagement with your app. It also provides insights on app usage. Analytics reports help you understand the user behavior and hence better decisions can be made regarding app marketing and performance optimizations. You can generate reports based on different parameters, such as device types, custom events, user location, and other properties. Analytics can be configured for Android, iOS, and C++ and Unity apps.

Cloud Messaging

Any Realtime app needs to send Realtime notifications. Firebase Cloud Messaging (FCM) provides a platform that helps you send the messages and notifications to the app user in Realtime. You can send hundreds of billions of messages per day for free across different platforms: Android, iOS, and web. We can also schedule the message delivery—immediately or in future. Notification messages are integrated with Firebase Analytics, so no coding is required to monitor user engagement.

Service Workers are supported on the following browsers:

  • Chrome: 50+
  • Firefox: 44+
  • Opera Mobile: 37+
// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function() {
 console.log('Notification permission granted.');
 // Retrieve the Instance ID token for use with FCM.
 // ...
})
.catch(function(err) {
 console.log('Unable to get permission to notify.', err);
});

Note

The FCM SDK is supported only in HTTPS pages because of service workers, which are available only on HTTPS sites.

Dynamic Links

Dynamic Links are URLs that help you redirect users to a specific content location in your mobile app or web application. If a user opens a dynamic link in a Desktop browser, the respective web page will be open, but if a user opens it up in your Android or iOS, the user will be redirected to the respective location in your Android or iOS. In addition, Dynamic Links work across the app; the user will be prompted to install the app if it is not installed yet. Dynamic Links increase the chances of conversion of mobile web users to native app users. Dynamic Links as part of online social networking campaigns also increase app installation and they are free forever.

Remote config

How cool is it to change the color theme of your app without redeploying it on the app store? Yes, it is possible to make on the fly changes to your app through Firebase Remote Config. You can manage the app behavior and appearance through server-side parameters. For example, you can give the certain discount on a specific group of audience based on the region without any redeployment of your app.

Invites

Generally, everybody refers the good apps to their friends and colleagues. We do it by copying and pasting the app links. However, it doesn't always work, due to a number of reasons, for example, the link was for Android, so an iOS user can't open it. Firebase Invites make it very simple to share the content or app referrals via email or SMS. It works with Firebase Dynamic Links to give the users the best experience with their platform. You can associate the Dynamic Links to the content you want to share and Firebase SDK will handle it for you, giving the best user experience to your app users.

App indexing

For any app, it is equally important to get the app installed as well as to retain those users with some engagement. To re-engage the users who have installed your app, App indexing is a way to go. With Google search Integration, your app links will be shown whenever users will search for the content your app provides. Also, App Indexing helps you improve Google search ranking for your app links to show them in top search results and autocompletion.

AdMob

The ultimate goal of the app developer is mostly to monetize it. AdMob helps you monetize your app through in-app advertising. You can have different kinds of ads, such as a banner ad, a video ad, or even a native ad. It allows you to show the ads from AdMob mediation platform or from Google Advertisers. AdMob mediation platform has Ad optimization strategy built to maximize your revenue. You can also see the monetization reports generated by AdMob to define your product strategy.

AdWords

One of the best marketing strategies in today's world is online advertisements. Google AdWords helps you reach the potential customers or app users through ad campaigns. You can link your Google AdWords account to your Firebase project to define the specific target audiences to run your ad campaigns.

Now that we have an understanding of all the products of Firebase platform, we can mix and match these products to solve the common development issues and get the best product out in the market.