Advertisement
  1. Code
  2. NativeScript
Code

Code a Real-Time NativeScript App: Social Login and Firebase

This post is part of a series called Code a Real-Time NativeScript App.
Code a Real-Time NativeScript App: SQLite
Code a Real-Time App With NativeScript: Push Notifications

NativeScript is a framework for building cross-platform native mobile apps using XML, CSS, and JavaScript. In this series, we're trying out some of the cool things you can do with a NativeScript app: geolocation and Google Maps integration, SQLite database, Firebase integration, and push notifications. Along the way, we're building a fitness app with real-time capabilities that will use each of these features.

In this tutorial, you'll learn how to add Facebook login to your NativeScript app. You'll also learn how to use Firebase to store walking sessions data in the fitness app. 

What You'll Be Creating

Picking up from the previous tutorial, let's now add the content for the social tab. By default, a button for logging in with Facebook is displayed like this:

not logged in

When a user logs in for the first time, the Facebook app asks for permission to access the public profile and email address:

Facebook permissions

It also asks for the friend list as an added permission. 

Once the user is logged in, the following screen is displayed:

Social tab

This is where the info for the currently logged-in user and the leaderboard for the walking sessions are displayed. Note that only the latest walking session is recorded.

Setting Up the Project

If you have followed the previous post in this series, on SQLite, you can simply use the same project and build the features that we will be adding in this tutorial. Otherwise, you can create a new project and copy the starter files into your project's app folder.

After that, you'll also need to install the geolocation, Google Maps, and SQLite plugins:

Once installed, you need to configure the Google Maps plugin. You can read the complete instructions on how to do this by reading the section on Installing the Google Maps Plugin in this earlier tutorial.

After that, you also need to install fecha, a library for formatting dates: 

Once all that is done, you should be ready to follow along with this tutorial.

Running the Project

You can run the project by executing tns run android. But since this app will use the geolocation functionality, I recommend you use a GPS emulator for quickly setting and changing your location. You can read about how to do so in the section on Running the App in the earlier tutorial.

Setting Up a Firebase App

The first thing that you need to do when working with Firebase is to create a Firebase app. You can do that by going to console.firebase.com and clicking on Add project. Enter the name of the project and click the Create project button. Be sure the name of the project is the same as the name of the app. In this case, the app ID is com.yourname.fitApp so the name of the app is fitApp.

create Firebase project

Once the app is created, you will be redirected to the app's dashboard page. From there you can click on Add Firebase to your Android app, enter the app ID, and click on the Register App button.

Add Firebase to Android app

Next, download the google-services.json file and copy it to the app/App_Resources/android directory. That file contains all the settings needed by the app to communicate with Firebase.

The next step stated in the Firebase dashboard is to include the Firebase SDK. But that's already done in the plugin, so we no longer have to do it.

Setting Up a Facebook App

Since we're going to use Facebook login, we also need to create a Facebook app. Go to developers.facebook.com and create a new Facebook app:

Create Facebook app

Once the app is created, you'll be redirected to the app dashboard. From there, click on the + Add Product menu and select Facebook Login.

Under the Client OAuth Settings, enable everything except Force Web OAuth Reauthentication and Login from Devices. For the Valid OAuth redirect URIs, you can get that by going back to the Firebase dashboard, clicking on Authentication, and enabling Facebook as an authentication method:

Authentication methods

Before you can enable it, you have to enter the Facebook app ID and app secret key. You can get that from the dashboard of the Facebook app you created earlier.

Once that's done, click on Save and copy the OAuth redirect URI over to the Facebook app settings. Don't forget to save the changes.

Next, you also need to add Android as a platform. You can do that by going to the Basic Settings and clicking on Add Platform:

Android settings

Set com.yourname.fitApp as the value for Google Play Package Name and com.tns.NativeScriptActivity for the Class Name.

Note that if you're going to release the app to the app store later on, you will need to generate a hash for the app's .apk file and add it under the key hashes field. Also note that for testing, you will only be able to use the Facebook developer account that you used to create the app. If you want to add other Facebook accounts for testing, you can add them under oles.

Installing the Firebase Plugin

In order to integrate Firebase, we need to install the Firebase plugin for NativeScript. This makes it easier to implement Facebook login and the real-time database feature in Firebase:

Once it's done installing, the installer is going to ask you a few questions regarding the Firebase features that you will use in the app. Answer yes for the Facebook login and no for the rest. 

Configuring Facebook Integration

You need to let the app know which Facebook app it's going to talk to. You can do that by opening the app\App_Resources\Android\AndroidManifest.xml file and adding <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/> under the <application> tag:

Next, create an app\App_Resources\Android\values\facebooklogin.xml file and add the following:

Be sure to replace YOUR_FACEBOOK_APP_ID with the app ID of the Facebook app you created earlier.

Solving Build Errors

If you're getting build errors after installing the plugin, be sure to check the Known issues on Android section in the repo's README. If your specific issue is not there, try to dig through the issues page.

As for me, the main issue that I had was a compatibility issue with the Google Maps plugin. Since that plugin also uses Google Play Services, there was a conflict with different versions being used. To solve that, I had to open the app/App_Resources/Android/app.gradle file and specify the Google Play Services version to use:

At the time of writing of this tutorial, it's at 11.0. But make sure to check which version is currently installed for you via the Android SDK.

Once that's done, you have to uninstall the android platform (tns platform remove android) and try to run the app once again (tns run android).

If that doesn't work for you and you're still getting the same build error, you might need to start all over by creating a new project. But this time, try to install the Firebase plugin before the Google Maps plugin. Then do the necessary configuration changes before trying to run the app.

Adding the Code

Now we're ready to add the code. We'll first add the XML, then the JavaScript, and finally the CSS code.

Adding the UI Markup

We'll be working primarily inside the social tab view. First, add the markup for displaying the info for the currently logged-in user as well as a button for logging out:

Below is the markup for displaying the leaderboard. This loops through the friends_data to display the user name, distance and steps made by the user's friends as well as the user.

If no user is currently logged in, we display the button for logging in with Facebook:

Importing the Libraries

Open the main-view-model.js file and add the following below the code for importing the fecha library:

We're using nativescript-plugin-firebase to talk to Firebase, http to make HTTP requests to Facebook's Graph API, and application-settings to persist the user's login data.

Initializing Firebase

Next, initialize Firebase with the init() function. This accepts an object which contains options for the different features supported by Firebase (e.g. authentication, real-time database, cloud messaging). 

Below, we're adding the persist option, which makes Firebase save data locally so the app can still be used while offline. Later on, we'll be adding the listener for when the authentication status changes (when the user logs in or logs out of the app).

Logging a User In

Next, add the code that will be executed when the user taps on the button for logging in to Facebook. This uses the login function, which accepts an object containing the type and facebookOptions

The type is the authentication method to be used for logging in. In this case, it's Facebook. facebookOptions is an object containing an array named scope. The elements of this array are the permissions that you want the app to request from the user. 

Once the user has logged in and agreed to all the permissions being requested, the promise resolves and executes the first function passed to then(). The Facebook user details are passed as an argument to this function, but the only thing we need is the access token. We can use this later to make requests to Facebook's Graph API in order to get additional information.

Next, we'll issue a query to the Firebase database to check if the user already exists or not. For this, we use the query() method. This accepts the function to execute when a response is returned as the first argument. The second argument is the path in which the query is performed, and the third is the query itself. 

If the user already exists, query() will return the user's data. We then save the data locally using application settings. We'll be needing to access this data later when we listen for auth status changes, and when we update the latest walking session of the user on Firebase.

Create a New User

Now let's add the code for saving the data for a new user. Start by creating the object which contains the user data. Then make a request to Facebook's Graph API to get the user's Facebook ID (which is valid for this specific app only). 

Later on, we will be using this ID to check if a specific Firebase user is a friend of the current user. Firebase doesn't return this ID when you log in, which is why we need to make a separate request. 

Once a response is returned, we'll use Firebase's push() method to save the user's data in the /users path. This returns the key which serves as the ID for this specific user. We're going to use it later to update the user's last walking session. That's why we also need to save it locally along with the user's data and the Facebook access token.

Now that we've added the code for logging a user in, the next step is to go back to the firebase.init() call, and add onAuthStateChanged. This function will get executed every time the auth status changes (when a user logs in or out). If a user is logged in, we want to update the UI to show the current user. 

Note that we're wrapping it inside setTimeout() with a five-second delay because it takes a few seconds after logging in for the user's data (Firebase user key, Firebase user, and Facebook Access Token) to be available. 

Next, we add the code for getting the user's friends. The graph API returns the ID and the name for each of the user's friends, but we only need the IDs. We also need to push the ID for the current user since we're going to display it in the leaderboard as well.

Displaying the Leaderboard

Next, add the code for listening for changes in the database. Up until now, we haven't really implemented the "real-time" part of this app. This is the time when we finally add it. 

For this, we use the addValueEventListener() method. This accepts the function that you want to execute when a change is made to the path you specified as a second argument. The whole value (result) is passed in as an argument to this function. 

There's really no functionality to specify a query to only filter the result by specific IDs. So using the array of friend IDs (friends_ids), we loop through the result and check if the current row is the current user or one of their friends. Only then do we push the value for the current row. From there, we just sort and format the data for displaying in the UI.

Updating the Latest Walking Session

When the user stops tracking their current location, we update the distance and steps of the user on Firebase:

Logging the User Out

Next, add the code for logging the user out. This resets the UI to a state where the user isn't logged in, and it also clears out the local data.

Adding the Styles

Finally, open the app/app.css file and add the following below the existing code:

Conclusion

That's it! In this tutorial you've learned how to integrate Facebook login and Firebase into a NativeScript app. As you might have noticed in the documentation for the NativeScript Firebase plugin, you can actually do a lot more with this plugin. In fact, we will be using its Cloud Messaging feature in order to implement the last feature for this app: Push Notifications. So stay tuned for that!

And in the meantime, check out some of our other posts on NativeScript and cross-platform mobile apps!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.