As an entrepreneur/mentor, I’ve been pitched a ton of great ideas for business apps. Without exception every one that had any worth has involved a server storing data. So if we care about the real-world use of Flutter, it would be criminal to ignore talking to a production-ready server.
- 1.
Firebase and Flutter are both Google products, so there are a few synergies.
- 2.
Firebase is at least as good as, and in some ways better than, the other options.
- 3.
Firebase is (fairly) easy to set up and free for low volumes – perfect for learning and testing.
- 4.
Firebase has been getting a ton of attention in the developer community lately. It is becoming the tech that hiring managers and recruiters want to see on your resume.
- 5.
We had to pick one, so why not Firebase? ¯\_(ツ)_/¯
Firebase at a very high level
How to set up a Firebase project
How to make it work with our eventual iOS and Android apps
Integrating it in our Flutter app with authorization
Reading Firestore data into our Flutter app
Querying data in Flutter
Changing data in Flutter
Deleting data in Flutter
So that will be our game plan for this chapter. Let’s start with an intro to Firebase itself.
Introducing Firebase
Google Firebase is a set of server-side services and tools. If you use Firebase, you don’t need to buy or rent your own server. No applying security patches or updating software. No organizing backups. No configuring of firewalls. No intrusion detection systems. No anti-malware definition maintenance. No paying an ISP to connect to the Internet. Basically, you’re trusting Google to handle all of the things you’d do with your own server. Of course a server exists, but you and I don’t have access to the OS so we have neither the responsibility nor the ability to maintain it. How freeing is that?
Cloud Firestore – A database with an API to read and write data
Cloud Functions – Logic that is kicked off by an API call
Authentication – Single sign-on to allow users to securely log in to your app using their social accounts or a username/password combination
Let’s discuss each very briefly and then extend last chapter’s example Flutter app to read and write from Firestore.
Cloud Firestore
We want a database that all apps can read from and write to. Firestore provides a NoSQL database with storage and tools to access that data. Being NoSQL it is highly flexible, maybe more flexible than you’re comfortable with. If you’ve worked with MongoDB, Cassandra, or CouchDB, then you know what we’re talking about here. The major difference with Firestore is the fact that the database itself and its backend engine are maintained by Google instead of by you and me. All we need to do is access the data.
Firestore exposes API endpoints for the data. After your app identifies itself to Firestore, it can read and write data at those endpoints. Kind of sounds like the RESTful interface we discussed in the last chapter, right? Firestore does support an interface that has some features of REST, but it is different enough that I wouldn’t categorize it as RESTful. Instead, we use a Dart library that takes care of the heavy lifting of authenticating our app and setting up private communications. We will call methods in that library like Firestore.get(‘people’) or Firestore.set(‘categories’). This turns out to be much more streamlined once we set it up. (But the setup isn’t super simple.)
Cloud Functions
Your app is almost certainly involved in processing data. Some of those algorithms might be very, very complex. But the fact is that your users’ devices are probably more than capable of handling those things.
“So why not just process everything in my app? ”, you ask. Because if it is on the device, the algorithms could be reverse-engineered by any attacker who downloads your Flutter app. Any secret business processes will be exposed and the logic could be tampered with. Any of your API keys would be stored on your device and could be read. So we would rather not put any sensitive data or processing on the device. Let’s put it on the server where it’s out of reach.
And what about processes or data that require sharing between two or more apps? You need a server for those things.
Consuming a third-party API
Processing server-side files like spreadsheets
Extracting, processing, transforming, and loading large data sets
Running a chatbot or chat application
Image analysis like face detection or recognizing and extracting text
Large image processing like blurring offensive images
Text analysis like intent detection
Machine learning and AI
Ordering a product from an ecommerce store like Walmart or Amazon
Cloud Functions are written in JavaScript and run on demand in a Node environment on Google’s servers when certain triggers fire like a record is added to Firestore or updated in Firestore, a user logs in, or someone simply makes an Ajax request to a particular URL .
Authentication
Firebase Authentication makes it (relatively) easy to add authentication to your app. Sure, you could add usernames and passwords to your app by brute force, but you’d have to worry about setting up the user tables and writing the authentication logic and hashing the passwords and handling forgotten passwords and all that. With Firebase Authentication, you get all of that functionality along with authentication via Facebook, Github, Twitter, and of course Google itself. Your users can choose to use their own username/password combinations or even do two-factor authentication by SMS message on their mobile devices .
Setting up Firebase itself
All these features and more are available with Firebase. If you want to try out Firebase, it is fun and free and a great learning experience. Besides, it’ll give us an opportunity to try out our newly acquired Ajax knowledge in a live read/write environment. We’ll let that be our goal over the next pages.
First, you must have an account with Google. If you don’t have a Google account, handwrite a letter to Google, place a stamp on it, and snail mail it to “Google Inc., Mountain View, CA 94043.”2
Go ahead and sign in to your Google Account and visit http://firebase.google.com to register an app with Firebase. Follow the prompts. You won’t be committing to anything nor pay any money for the basic account.
Over your career, you’ll probably be involved in multiple projects, some for learning purposes, some for your side hustles, and maybe even some for your main business. For this reason, Firebase allows users to have multiple projects. We’ll create one to work with.
Caution
The following steps are current as of the time of writing, but they can change. Take a look here for the most current steps: https://firebase.google.com/docs/flutter/setup.
(1) Creating a Firebase project
Now imagine that this project had a web interface and a database backend and was being accessed by a Flutter app on iPhones and on Androids. This would be one project with multiple apps. As with multiple projects, Google allows each project to have multiple apps. Each app will have its own settings since the environments all have different demands. Before we’re finished, we’ll set up one each for iOS and Android. But first, we should create our database and at least one collection (aka table).
(2) Creating the database
Choose to start it out in test mode just so we can easily verify that our code works. You’ll want to add rules in a real-world app which you can add at any time. Hit “Next”.
Tip
This is a NoSQL database which is different from traditional relational databases like MySQL, SQL Server, Oracle, Informix, and the like. First, the terminology is different (Table 12-1).
How you refer to things in different types of DB servers
Relational databases | NoSQL databases |
---|---|
Tables | Collections |
Records/rows | Documents |
Columns | Fields |
A NoSQL database does have keys and values, but they do not have a fixed structure. In other words, each document in a collection might have different fields than others in that same collection. This is the major difference between traditional databases and NoSQL databases and is the toughest thing to get used to.
You’ll now be able to see your lone document in the Cloud Firestore viewer. From here, you can add documents, delete documents, and alter documents.
It’s nice that we can maintain the database right from the Firebase web site, but our goal is obviously to do that from our app. So we must configure our iOS and Android apps to read from Cloud Firestore.
(3) Creating an iOS app
Click the iOS button.
Download GoogleService-info.plist and store it in the iOS/Runner/Runner directory (Figure 12-8). You’ll know you’re in the right folder when you see Info.plist. Don’t be distracted by the diagram they show you. It will look different because they’re showing the Xcode version of a project, but you’re working in a Flutter project.
At this point, when your app runs, it knows which Firebase account and project it is associated with. Only an app with this .plist file will be able to connect to your app. Of course, when you compile the app and distribute it to devices through the Apple App Store, they’ll all be connecting to this one Firebase account. This is normal and to be expected. Each user who runs it will check in with Firebase. You should see activity in your Firebase console. Firebase is now listening for it and will provide you with analytics data.
Since we’re creating a cross-platform app, we should probably also do the same with Android. Remember, they’re completely different environments so the steps will be different.
(4) Creating an Android app
That SHA-1 certificate is optional for most applications. You can leave it blank for now but go back and generate the certificate if you need it for Google Sign-in or phone number authentication.
Install the google-services.json file
This file has all kinds of important settings in it, especially the project numbers and app ids that will tell your app where to ask for data from Google Firestore. With all of this in a config file, you won’t have to hard-code it in your app’s source code.
Note that it should be saved in the app folder at the same level as the app-level build-gradle file. Speaking of which, our next step is to edit that file.
Adding to the gradle files
Tell the IDE to sync the gradle files. In Android Studio, you’ll see a “Sync now” link. Go ahead and click it .
(5) Adding FlutterFire plugins
Almost there! At this point we have the groundwork laid to use Firebase with our app. We just have to add the Firebase plugins for Flutter and start coding. It turns out that Google provides one common library for Firebase itself and one library plugin for each Firebase product. We’ll need the common library plugin and the Cloud Firestore plugin.
Of course if we use other Firestore products, we’ll need to add the appropriate plugin, but we won’t have to re-do any of the other preceding steps; once for the project is sufficient.
Using Firestore
Yes, that was a lot of setup, but we’re finally ready to consume and maintain data from the database. In order to make it easier on you to put these Firestore HTTP calls in context, we’ll use the Person examples from the last chapter, replacing the calls to our temporary/test server with calls to Firestore. Refer back to them and to the code from our github repository as you read through the next pages.
This will expose an object called Firestore that you can use to get to the database. In fact, Firestore.instance will point to your database as a whole. And Firestore.instance.collection(‘Foo’) will point to the entire Foo collection.
Note
Even though Firestore calls are HTTP calls behind the scenes, there is no need to enter API keys or create setups or post-processing the data or much of the other heavy lifting needed to make normal Ajax calls with Firestore. All of those tasks are abstracted away from you with the inclusion of the libraries which depend on the google-services.json and GoogleService-Info.plist files. As tedious as all that setup was, you can now see the payoff.
To get a collection
Tip
If you want to have a one-time read of the data without subscribing, omit the .snapshot() and it will return a simple array of Maps (aka array of objects). If you do that, you’ll want to use a FutureBuilder instead of a StreamBuilder.
To query
And unfortunately that’s about it. It does not support any fuzzy logic like wildcards, “contains,” or “like.” If you need full-text searching, the Firebase team recommends a third-party service like Algolia. See https://firebase.google.com/docs/firestore/solutions/search for more details.
To upsert
The word “upsert” means that if the document exists, it is updated, but if it does not exist, it is added. Firestore does both of these operations with the setData method.
Caution
Be careful. It is easy to create duplicates by forgetting the documentID when calling setData().
To delete
Obviously there is nothing returned from the delete so no need for a .then().
Where to go from here
You now understand how Flutter works and is architected
You can deftly handle the most useful built-in Flutter widgets
You can create custom widgets, both Stateless and Stateful
Your Flutter UX can be intuitive through layout widgets
You can make them look beautiful with styles
You’re able to navigate between scenes in a Flutter app
You can handle asynchronous activities including reading local data
You can read and write data through an HTTP/RESTful API
You can persist data permanently in a robust, scalable server
Wow! That’s a ton of stuff! But there are tons more to learn. Heck, even veterans should continue learning. Let me recommend some resources for you to continue to explore and learn.
First, get involved in the Flutter community (of which I’m a member). Start with their Slack channel at http://flutterStudyGroup.slack.com. Read their articles at https://medium.com/flutter-community. And join us via Zoom on Wednesdays for Hump Day Q & A at https://tinyurl.com/humpdayqanda where you can talk live with Flutter devs literally around the globe, ask questions, and even pair program to solve problems. The top Flutter developers in the world hang out there, eager to help you with your Flutter issues.
I also recommend that you subscribe to two free curated emails chock full of Flutter articles, videos, tutorials, and more. Each is delivered freshly baked to your inbox once a week. Flutter Weekly has a couple dozen resources per newsletter. Subscribe here: http://bit.ly/subscribe_to_flutter_weekly. Flutter Press Weekly is smaller each week because it is more selective in the resources shared. You can subscribe to Flutter Press Weekly at http://bit.ly/subscribe_to_flutter_press_weekly. Reading these regularly will keep your finger on the pulse of the latest developments in Flutter.
Google’s Flutter team also has some cool resources. A great place to begin is the Flutter documentation at https://flutter.dev/docs. Parts of it are awfully dry to read but is the definitive resource if you’re looking up Flutter widgets and APIs. On the other end of the spectrum are their videos, hugely entertaining and easy to digest. I recommend that you subscribe at http://bit.ly/flutter_youtube_channel. If you see a “Widget of the Week” video in there, click it immediately! They are one or two minutes at most and will give you a functional understanding of the widget in question faster than anything else. Google is resetting the bar for documentation in their video channel.
I’ve been overwhelmed with the passion of the Flutter community! If these three mega-resources don’t do it for you, there are tons and tons of others out there for the asking. Get involved with your fellow Flutter devs, and if you see me hanging out in one of them, please stop and say hello. Thanks so much for reading!