14
Adding the Firebase and Firestore Backend

WHAT YOU WILL LEARN IN THIS CHAPTER

  • How to create a Firebase project
  • How to register the iOS and Android projects to use Firebase
  • How to add a Cloud Firestore database
  • How to structure and create a data model for the Cloud Firestore database
  • How to enable and add Firebase authentication
  • How to create Firestore security rules
  • How to create the Flutter client app base structure
  • How to add Firebase to iOS and how to add the Android projects with the Google service files
  • How to add the Firebase and Cloud Firestore packages
  • How to add the intl package to format dates
  • How to customize the AppBar and BottomAppBar look and feel by using the BoxDecoration and LinearGradient widgets

In this chapter, in Chapter 15, and in Chapter 16, you'll use techniques that you have learned in previous chapters along with new concepts and tie them together to create a production‐level mood‐journaling app. In the previous chapters, you created many projects that taught you different ways to implement specific tasks and objectives. In a production‐level app, you need to combine what you have learned to improve performance by redrawing only the widgets with data changes, pass state between pages and up the widget tree, handle the user authentication credentials, sync data between devices and the cloud, and create classes that handle platform‐independent logic between mobile and web apps.

Because Google has open‐sourced Flutter support for desktop and web apps, the Firebase backend services can be used for Flutter desktop and web apps, not just mobile. That's why in this chapter you'll learn how to develop a production‐level mobile app.

Specifically, you'll learn how to use authentication and persist data to a cloud database by using Google's Firebase (backend server infrastructure), Firebase Authentication, and Cloud Firestore. You'll learn how to create and set up a Firebase project using Cloud Firestore as the cloud database. Cloud Firestore is a NoSQL document database to store, query, and sync data with offline support for mobile and web apps. Did I say offline? Yes, I did. The ability of a mobile app to function while an Internet connection is not available is a must‐have feature that users expect. Another great feature of using Cloud Firestore is the ability to synchronize live data between devices automatically. The data syncing is fast, allowing collaboration between different devices and users. The amazing part of using these powerful features is that you don't have to deal with setting up and managing the server's infrastructure. This feature allows you to build serverless applications.

You'll configure the Firebase backend authentication provider, database, and security rules to sync data between multiple devices and platforms. To enable authentication and database services for the client‐side Flutter project, you'll add the firebase_auth and cloud_firestore packages. In Chapter 15 and Chapter 16 you'll learn how to implement app‐wide and local state management by using the InheritedWidget class and maximize platform code sharing by implementing the Business Logic Component pattern. You'll use app‐wide and local state management to request data from different service classes.

WHAT ARE FIREBASE AND CLOUD FIRESTORE?

Before you start configuring, let's take a look at what Firebase encompasses. Firebase consists of one platform with a multitude of products that share and work together. Firebase handles the entire backend server infrastructure connecting iOS, Android, and web apps.

Build Apps

  • Cloud Firestore—Store and sync NoSQL data in documents and collections between devices
  • Real‐time database—Store and sync NoSQL data as one large JSON tree between devices
  • Cloud storage—Store and serve files
  • Cloud functions—Run backend code
  • Authentication—Secure user's authentication
  • Hosting—Deliver web app assets

Ensure App Quality

  • Crashlytics—Real‐time crash reports
  • Performance monitoring—App performance
  • Test lab—Test apps on devices hosted by Google

Grow Business

  • In‐app messaging—Send users messages
  • Google Analytics—Perform app analytics
  • Predictions—User segmentation based on behavior
  • A/B testing—Optimize app experience
  • Cloud messaging—Send messages and notifications
  • Remote config—Modify the app without deploying a new version
  • Dynamic links—App deep links
  • App indexing—Drive search traffic to a mobile app

Wow, this sounds amazing, but does it cost a fortune? Actually no; Google offers the Spark Plan, which gives you free access to the majority of the products, especially Cloud Firestore. You can view the details and restrictions at https://firebase.google.com/pricing.

In this chapter, I'll focus on using Cloud Firestore to store and sync data between devices. For general information on Firebase, you can browse https://firebase.google.com.

What is Cloud Firestore? It stores data in documents organized in collections, similar to JSON. It can scale complex and hierarchical data by using subcollections within documents. You'll take a detailed look at it in the next section, “Structuring and Data Modeling Cloud Firestore.” It offers offline support for iOS, Android, and web apps. For the iOS and Android platforms, the offline persistence is enabled by default, but for the Web, the offline is disabled by default. To optimize querying data, it supports indexed queries with sorting and filtering. It can use transactions that automatically repeat until the task is completed. Data scaling is automatically handled for you. You use mobile SDKs to integrate different features of Firebase products into your apps.

Structuring and Data Modeling Cloud Firestore

To understand the Cloud Firestore data structure, let's compare it to a standard SQL Server database (see Table 14.1). The SQL Server database is a relational database management system (RDBMS) that supports table and row data modeling (Figure 14.1). The comparison is not a one‐to‐one but a guideline since the data structures differ.

TABLE 14.1: Data structure comparison

SQL SERVER DATABASE CLOUD FIRESTORE
Table Collection
Row Document
Columns Data
Schematic of SQL Server database data model.

FIGURE 14.1: SQL Server Database Data Model

In Cloud Firestore, a collection can contain only documents. A document is a key‐value pair and can optionally point to subcollections. Documents cannot point to another document and must be stored in collections (Figure 14.2).

Schematic of Cloud Firestore data model.

FIGURE 14.2: Cloud Firestore Data Model

What is the collection's responsibility? Collections are containers for documents; they hold them the same way a folder holds pages.

What is the document's responsibility? Documents hold data that is stored as a key‐value pair similar to JSON. Documents support extra data types that JSON does not support. Each document is identified by name, and they are limited to 1MB in size (see Table 14.2).

TABLE 14.2: Cloud Firestore sample data

TYPE VALUE
Collection journals
Document R5NcTWAaWtHTttYtPoOd
Document data as key‐value pair date: "2019‐0202T13:41:12.537285"
mood: "Happy"
note: "Great movie."
uid: "F1GGeKiwp3jRpoCVskdBNmO4GUN4"

Let's take a look at the Cloud Firestore sample data as JSON objects and in the Cloud Firestore console (Figure 14.3). Notice that the document name is a unique ID that can be automatically created by Cloud Firestore, or you can manually generate it.

Screenshot of collection and document.

FIGURE 14.3: Collection and Document

{
  "journals":[
   {
     " R5NcTWAaWtHTttYtPoOd1":{
      "date": "2019-0202T13:41:12.537285",
      "mood":"Happy",
      "note":"Great movie."
      "uid": " F1GGeKiwp3jRpoCVskdBNmO4GUN4",
     }
   }
  ]
} 

Cloud Firestore supports many data types such as array, Boolean, byte, date and time, floating‐point number, geographical point, integer, map, reference, text string, and null. One of the major advantages of using Cloud Firestore is the automatic syncing of data between devices and the ability of the client app to continue working offline while the Internet is not available.

Viewing Firebase Authentication Capabilities

Adding security to an app is extremely important in keeping the information private and safe. Firebase Authentication provides built‐in backend services accessible from the client's SDK to support full authentication. The following is a list of the currently available authentication sign‐in providers:

  • Email/Password
  • Phone
  • Google
  • Play Games (Google)
  • Game Center (Apple)
  • Facebook
  • Twitter
  • GitHub
  • Anonymous

Each authentication sign‐in provider is disabled by default, and you enable the providers needed for your app specs (Figure 14.4). I'll walk you through how to enable a sign‐in provider later in this chapter.

Screenshot of Firebase Authentication's sign-in providers.

FIGURE 14.4: Firebase Authentication's Sign‐In Providers

An important note on using the Anonymous provider is that if the user deletes the app from the device and reinstalls it, a new anonymous user is created and will not have access to the previous data. The data from the original anonymous user is still stored on the backend, but the client app has no way of knowing the original anonymous user ID since the app was deleted from the device. One example of using the Anonymous sign‐in provider is to allow the user free access to the app and allow a paid upgrade path to advanced features.

From your mobile app, you retrieve the user's authentication credentials from any of the available sign‐in providers. You pass these credentials to the client Firebase Authentication SDK, and the Firebase backend services verify whether credentials are valid and return a response to the client app. If the credentials are valid, you allow the user to access the data and pages in the app depending on the security rules that you will learn about in the next section, “Viewing Cloud Firestore Security Rules.”

Once a particular sign‐in provider is enabled, you use the Firebase Authentication SDK to create a Firebase User object saved on the Firebase backend. The Firebase User object has a set of properties that you can customize, except for the unique ID. You can customize the primary email address, name, and a photo URL (usually the user's photo or an avatar). By using the Firebase User object's unique ID, you bind all the data that the user has created to the ID.

Viewing Cloud Firestore Security Rules

To secure access to collections and documents, you implement Cloud Firestore security rules. In the previous section, you learned that you create a Firebase User object through the Firebase Authentication SDK. Once you have the Firebase User object's unique ID, you use it with Cloud Firestore security rules to secure and lock data to each user. The following code shows the security rules that you'll create for securing the Cloud Firestore database:

service cloud.firestore {
 match /databases/{database}/documents {
  match /journals/{document=**} {
   allow read, write: if resource.data.uid == request.auth.uid;
   allow create: if request.auth.uid != null;
  }
 }
}

The rules are editable from the database rules page on the Firebase console website. The rules consist of using the match statements to identify documents, with the allow expressions to control access to the documents. Every time you change the rules and save them, a history of changes is automatically created, allowing you to revert changes if needed (Figure 14.5).

Screenshot of Cloud Firestore rules.

FIGURE 14.5: Cloud Firestore Rules

Let's take a look at an example that requires rules to allow a user to read and write documents assigned to them. The first match /databases/{database}/documents declaration tells the rules to match any Cloud Firestore Database in the project.

match /databases/{database}/documents

The second and the main part of understanding is to use the match statement to point to the collection and expression to evaluate, as in match /journals/{document=**}. The journals declaration is the container name, and the expression to evaluate is document=** (all documents for the journals collection) wrapped inside curly brackets. Inside this particular match, you use the allow expression for the read and write privileges by using the if statement to see whether the resource.data.uid value equals the request.auth.uid. The resource.data.uid is the uid field inside the document, and the request.auth.uid is the logged‐in user's unique ID.

match /journals/{document=**} {
 allow read, write: if resource.data.uid == request.auth.uid;
}

You can break down the rules even further by using a match statement for each read or write action. For the read rule, it can be broken into get and list. For the write rule, it can be broken into create, update, and delete.

// Read
allow get: if <condition>;
allow list: if <condition>;

// Write
allow create: if <condition>;
allow update: if <condition>;
allow delete: if <condition>;

The following example uses the create rule to allow only authenticated users to add new records by checking whether the request.auth.id value is not equal to a null value:

  allow create: if request.auth.uid != null;

CONFIGURING THE FIREBASE PROJECT

You now understand how Cloud Firestore stores data and the benefits of syncing multiple devices with offline data persistence. The offline feature works by caching a copy of the app's active data, making it accessible when the device is offline. Before you can use Cloud Firestore in your app, you need to create a Firebase project.

A Firebase project is backed by the Google Cloud Platform, which allows apps to scale. The Firebase project is a container that supports sharing features such as the database, notifications, users, remote config, crash reports, and analytics (many more) between the iOS, Android, and web apps. Each account can have multiple projects, for example to separate different and unrelated applications.

ADDING A CLOUD FIRESTORE DATABASE AND IMPLEMENTING SECURITY

You've learned how to create a Firebase project, making it possible to add the Cloud Firestore database and Firebase Authentication. You learned about the different available sign‐in methods, and in this section, you'll walk through how to implement security rules and enable an authentication sign‐in method—specifically, an email/password authentication provider.

BUILDING THE CLIENT JOURNAL APP

The process of creating the mood‐journaling app spans from this chapter to Chapter 16. In this section, you'll create the base structure of the app and configure the iOS and Android projects to use Firebase Authentication and the Cloud Firestore database. You'll modify the basic look and feel of the app by using color gradients.

The goal of the mood‐journaling app is to have the ability to list, add, and modify journal entries by collecting a date, a mood, a note, and the user's ID. You'll learn to create a login page to authenticate users through the email/password Firebase Authentication sign‐in provider. The main presentation page implements a ListView widget by using the separated constructor sorted by DESC (descending) date, meaning last entered record first. The ListTile widget easily formats how you'll display the List of records. The journal entry page uses the showDatePicker widget to select a date from a calendar, a DropdownButton widget to select from a list of moods, and a TextField widget to enter the note.

Adding Authentication and Cloud Firestore Packages to the Client App

It's time to create the Flutter app and add the Firebase Authentication and Cloud Firestore SDKs by installing the Firebase Flutter packages. The Flutter team authors the different Firebase packages, and like other packages, the full package source code is available on the appropriate package's GitHub page.

You'll install the firebase_auth, cloud_firestore, and intl packages. You'll download the Google service files (config) for iOS and Android that contain properties needed to access the Firebase products from the client app.

Adding Basic Layout to the Client App

In the previous section, you learned how to add and configure Firebase Authentication and the Cloud Firestore database. The next step is to work on the Flutter project to customize the look and feel of the journal app.

You'll customize the app's background color by setting the MaterialApp canvasColor property to a light shade of green. The AppBar and BottomAppBar customizations show a color gradient from light green to a very light shade of green, merging with the app's background color. To achieve the color effect, set the BoxDecoration gradient property by using a LinearGradient widget that you learned in Chapter 6, “Using Common Widgets.”

Adding Classes to the Client App

You'll need to create two classes to handle formatting dates and tracking the mood icons. The FormatDates class uses the intl package to format dates. The MoodIcons class stores reference to the mood icons title, color, rotation, and icon.

SUMMARY

In this chapter, you learned how to persist and secure data over app launches by using Google's Firebase, Firebase Authentication, and Cloud Firestore. Firebase is the infrastructure that doesn't require the developer to set up or maintain backend servers. The Firebase platform allows you to connect and share data between iOS, Android, and web apps. You configure the Firebase project with the online web console. In this chapter, you registered both the iOS and Android projects with the com.domainname.journal package name to connect the client app to the Firebase products.

You created a Cloud Firestore database that safely stores the client app's data in a cloud database. Cloud Firestore is a NoSQL document database to store, query, and sync data with offline support for mobile and web apps. You structure and data model Cloud Firestore databases by using a collection to store documents that contain data as a key‐value pair similar to JSON.

Securing the Cloud Firestore database is done by creating Cloud Firestore security rules. The security rules consist of using the match statements to identify documents, with the allow expression to control access.

Firebase Authentication provides built‐in backend services that are accessible from the client's SDK, which supports full user authentication. Enabling the email/password authentication sign‐in provider allows users to register and log in to the app. By passing the user credentials (email/password) to the client's Firebase Authentication SDK, the Firebase backend services verify whether the credentials are valid and return a response to the client app.

You created the base structure of the client mood‐journaling app and connected it to the Firebase services by installing the firebase_auth and cloud_firestore packages. You configured the client iOS and Android projects to use Firebase. You added the GoogleService‐Info.plist file to the iOS project and the google‐services.json file to the Android project. The Google service files contain properties needed to access the Firebase products from the client app. You modified the base look and feel of the app by using the BoxDecoration widget, with the gradient property set to a LinearGradient to create a smooth light green color gradient.

In the next chapter, you'll learn how to implement app‐wide and local state management by using the InheritedWidget class and how to maximize platform code sharing and separation by implementing the Business Logic Component pattern. You'll use state management to implement Firebase Authentication, access the Cloud Firestore database, and implement service classes.

image WHAT YOU LEARNED IN THIS CHAPTER

TOPIC KEY CONCEPTS
Google's Firebase Firebase consists of one platform with many products that work together as a backend server infrastructure connecting iOS, Android, and web apps.
Cloud Firestore You learned how to structure and data model the Cloud Firestore database. Cloud Firestore is a NoSQL document database to store, query, and sync data with offline support.
Firebase Authentication Firebase Authentication provides built‐in backend services accessible from the client's SDK, supporting full authentication.
Cloud Firestore Security Rules To secure access to data, you learned how to implement Cloud Firestore security rules. Rules consist of using the match statements to identify documents with the allow expressions.
Cloud Firestore collection A collection can contain only documents.
Cloud Firestore document A document is a key‐value pair and can optionally point to subcollections. Documents cannot point to another document and must be stored in collections.
firebase_auth package You learned how to add the firebase_auth package to enable authentication in the Flutter app.
cloud_firestore package You learned how to add the cloud_firestore package to provide database storing and cloud syncing in the Flutter app.
GoogleService‐Info.plist file You learned how to add the google‐services.json file to the iOS Xcode project to connect the client app to the Firebase services.
google‐services.json file You learned how to add the google‐services.json file to the Android project to connect the client app to the Firebase services.
For the Android project, you also learned how to modify the project and app‐level gradle files to use Firebase Authentication and Cloud Firestore.
Flutter app base layout You learned how to use the BoxDecoration widget by setting the gradient property to a LinearGradient list of colors to enhance the look and feel of the app.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset