Tutorial : MIT App Inventor + Firebase
MIT App Inventor has played a big role in bringing programming to a wide range of audience, primarily high school students. One of the challenges that I have faced while teaching this to a young audience has been that once you progress beyond a certain set of features in App Inventor applications, you get to a tricky situation where you need to explain persistence of data.
App Inventor 2 has good support for local persistence of data via TinyDB and TinyWebDB. The former is a local persistence solution and the later is a managed database solution in the cloud. While TinyDB is good, it is time to look at Firebase, the hosted real-time database in the cloud from Google.
Note: For the purpose of this beginner tutorial, I will be referring to Firebase as just the database and not the entire mobile development platform that it currently now is. If its been a while that you have looked at Firebase, I suggest you do so again — it offers a database, notifications, development tools, authentication, crash reporting, analytics and more.
My goal in this tutorial is to show you to write an Android application backed by a state of the art solution i.e. Firebase. We will not write any Java code for our Android application and instead rely on App Inventor. Programming for the masses needs to be simpler than writing low level programming code, isn’t it? Let’s see if you agree with me by the end of this post.
This tutorial is not an introduction to App Inventor 2 or setting up of its tools. There is great documentation available at the official site to help you do that. Check it out below if you need help on that. I will assume that you know how to navigate through App Inventor 2 and are familiar with Design and Blocks, the two key screens in any App Inventor 2 project.
Our Android Application — Bus Route Status
Our Android application is about an organization that runs a transport bus everyday to bring its employees to work every morning. This organization runs 4 buses every day in the morning, which start from different corners of the city (Mumbai in this case!) and then it navigates through the unforgiving Mumbai traffic to finally reach its office location.
In summary, we have 4 bus routes (Andheri, Borivali, Thane and Navi Mumbai). Each bus route consists of several stops.
The organization would like provide a simple Android application to its bus co-ordinators (1 or more per bus). The job of these bus co-ordinators is simple. They will use this Android app, select the bus route and then enter the last bus stop that the bus has just arrived at. If there are any issues/incidents with the bus route, they can note that down too.
All the commuters of this bus can also use this application to get the current status of the bus i.e. which route has just passed. They could then get a sense of where the bus was last and if there are any issues.
The bus route updates will all be captured in the Firebase database running in the cloud. We will also query the database whenever the user asks for a particular bus route status.
Firebase Setup
The first step for us is to setup the Firebase database in the cloud. The instructions are given below:
- Visit https://console.firebase.google.com/ and login with your Google account.
- You will see the welcome screen with two buttons as shown below:
- Click on Create New Project button.
- This will bring up the Create a project screen as shown below, where you will need to provide a project name. Note that you will need to provide a unique name for your project. Select a Country/region where you would like your database to be hosted. Click on Create Project.
- Be patient. This will create a Firebase database under the Spark Plan. This plan is free and is good enough for our scenario. As an example of what the Spark plan gives us, take a look at this table.
- To iterate again, we are only going to look at the Database feature of Firebase and not other services for now. Click on the Database link on the left. This will show up some details about your database as shown below:
- Important: Please note down your database URL as highlighted in the screen above. This is the unique database url that is available to the outside world for integration. In our case, the Android application that we shall be writing in App Inventor will be using this unique URL as our backend database. Simple!
- Another point to note here is that it shows the database name and a null next to it. This means that currently there is no data in the database. Keep this screen handy, you will be coming back to it and can see the database live here as it comes in. Even if not live, you can see what the data currently is in the database over here.
- Click on the Rules tab. You will notice that it has the following rules by default as shown below. Let’s not get too much into rules for now but it is sufficient to understand that why the magic text indicates is that to do database reads and writes, you will need to be authenticated. Firebase supports multiple authentication mechanisms, but we will keep it simple for now and not use any authentication. Note that what we are going to do is not good practice but it is ok for our tutorial here. What we are going to do is open up access to this Firebase database to allow anyone (everyone) to both read and write.
- To do that, simply start editing the text to the one that is shown below:
- Click on Publish. This will publish (associate) the rules with your database. It also indicates clearly (and which is good by the way) that we have defined our database to be accessed by the public (read and write). Boys and Girls, don’t try this at home (sorry … don’t try this in a live database).
That’s it. We have a Firebase database in the cloud, all ready for read and write. Now, all we need is to write this to our Android application.
Enter App Inventor 2 now for completing our Android application.
Writing our Android Application
Go ahead and login to App Inventor 2 now. Once logged in with your Google account, do the following:
- Click on Projects → Start New Project. This will bring up a screen where you can give a name to your project. Choose any name. I choose OfficeBusProject as shown below. Click on OK and you will be navigated to the Project Design window.
- The next step is for us to design our Application. We will keep things simple and the screenshot for the application is given below:
- Notice that I have added two non-visible components. The FirebaseDB component is available under the Experimental section of the Palette as shown below:
- The screenshot below shows the different User Interface components that reflect the single screen that we will be having in our application:
- The important thing to configure next is our FirebaseDB1 component that we added to the screen. Click on the FirebaseDB1 component and see the properties. App Inventor hosts a service in the backend where you can use their hosted (Default) version of Firebase, but we will be using our database that we created in the earlier section. So to do that, we will need to give the value in the FirebaseURL property as the one that you noted down earlier. Set that value in the FirebaseURL property and deselect the Default value (Set it to not selected). An example screenshot is shown below. Note that you can ignore the FirebaseToken and the ProjectBucket is set by default to your App Inventor Project Name. Leave it or change it to anything you like. This will have an impact on how your database values are finally stored, which we shall see in a while.
- Earlier, when we are talking about the application, we described that there will be 4 Bus Routes. These values will go into the spnBusRoute Spinner control. We set the values (Comma Separated) in the properties itself.
- The Bus Stop and Comments are free text fields that will be input by the bus coordinator themselves.
- The rest of the screen is self explanatory. As a Bus coordinator, you can select the Bus Route from the drop down. Then you can enter the values for the Bus Stop Name and Comments (if any) and click on the Update Bus Route button.
App Inventor blocks for Update Bus Route
Now switch over to the Blocks section of the application. All we need to do now on click on the Update Bus Route button is the following:
- Collect the values in the Bus Route, Bus Stop Name and Comments. There are no validations currently but that is something that could be an exercise for the student.
- Invoke the Firebase component StoreValue method. The StoreValue method takes two parameters, the tag and the valueToStore. Let us understand what this will do. As mentioned, we want to save the last bus stop name and any incidents(Comments). We would like to cleanly separate and organize this information for each bus route. So what we want is a hierarchical structure for each of the 4 Bus Routes.
Bus Route 1
| — — Last Updated Stop
| — — Comments
Bus Route 2
| — — Last Updated Stop
| — — Comments
Bus Route 3
| — — Last Updated Stop
| — — Comments
Bus Route 4
| — — Last Updated Stop
| — — Comments
So in other words, when we actually save the values, it would look something like this:
Borivali
| — — Last Updated Stop : <Stop-Name>
| — — Comments : <Stop-Comments>
Thane
| — — Last Updated Stop : <Stop-Name>
| — — Comments : <Stop-Comments>
Navi Mumbai
| — — Last Updated Stop : <Stop-Name>
| — — Comments : <Stop-Comments>
Andheri
| — — Last Updated Stop : <Stop-Name>
| — — Comments : <Stop-Comments>
- The entire set of blocks is given below. Note that we declare 3 variables for each of the values that we want to collect and initialize them to empty values. We then store the values from the user interface components into these values and then we invoke the FirebaseDB components’ StoreValue method twice. Once for the Bus Stop Name and the other for the Comments.
- Now try running the code for the first time. Just select one bus route and put in some values for bus stop name and the comments. Click on Update Bus Route button. If all is well, you will see an entry in the database. Go to the Firebase Console again and see the Database section. A sample run is shown below:
Cool, isn’t it?
- Now go ahead and do that for all the bus stops and even try to update a Bus Route with multiple stops, it will overwrite correctly the last value.
Trivia: Do note that while the Bus Route names are valid ones in Mumbai, the sample values used for the Bus Stops are not or maybe they are? Find out which ones are valid?
It is important that you see the almost real-time capabilities of Firebase here. While trying out the functions, keep your Firebase database console open and notice the values coming in. It makes for great viewing!
Error Handling
There could be an error while dealing with the Firebase service, since that is running in the cloud, needs connectivity from your Android application and more. It would be a good practice to have a block that can handle any Firebase error that is thrown and then show a user friendly message. The block for that is shown below:
App Inventor blocks for Get Latest Route Info
While ideally I would have liked to show a real-time update when the Bus Route (that is an exercise mentioned later), we will simply query the Firebase Database about a Bus Route and update a few labels in the Android app. All the user does is select a Bus Route from the dropdown list and click on the Get Latest Route Info button.
First up, we will write the set of blocks for the button handler. Keep in mind that data over the web is retrieved asynchronously. What this means is that we will make the call to get the values and then we will receive an event with data.
So, let’s look first at the set of blocks to ask for the Bus Route information:
We are using the GetValue method of the Firebase component. Notice how we are cleverly forming the path to the values for both Last Updated Stop and Comments. We are using the Bus Route Name and appending the “/Last Updated Stop” and “/Comments” text to retrieve the full path to their values. Notice the valueIfTagNotThere. If there is no value retrieved then we can give a default value to substitute for it (This is good practice).
The next thing to write is our block of codes which will get invoked once GetValue invocation actually results in a value being returned. To help retrieve that, there is a GotValue method in the Firebase component. The set of blocks are shown below. We have simple if blocks to check what the tag is and then use those values to update the respective Android Label fields.
This completes our tutorial and hopefully you get a sense of how easy it is to use Firebase and App Inventor 2 together. It makes for a great combination and I recommend some of the exercises shown below that you could use in your class.
Areas of improvement (Exercises for the Students)
There are multiple areas of improvements that you could do in the application. If you are a teacher, these are enhancements you could ask your students to do.
Here are a few of them:
- Different screens or apps for bus coordinators and just users.
- Provide validations for the Bus Stop Names and Comments. Ensure that it is not empty or has sensible values. Maybe provide a drop down list for the Bus Stop Names instead of Free form to avoid errors.
- Introduce the concept of a date and time for the bus journeys. Over time, this data could be used to do some analytics on whether the buses run on time, etc.
- Collecting a list of comments rather than overwriting the comment each time. Firebase supports that. Maybe we will have another tutorial on that.
- Capture location of the bus via App Inventor 2 and dump those location values in Firebase database too.
- A better UI (you would have guessed that from my UI skills!)
- Use Firebase Components’ DataChanged event. This will be fired whenever the data changes and you can then update the screen information accordingly:
Hope you enjoyed this tutorial. Please share your comments below.