# Start Implementing Google Auth With MongoDB Realm in Your Android App

Hello, everyone. I am Henna. I started with Mobile Application back in 2017 when I was a lucky recipient of the Udacity Scholarship. I had always used SQLite when it came to using databases in my mobile apps. Using SQLite was definitely a lot of boilerplate code, but using it with Room library did make it easier.

I had heard about Realm before but I got so comfortable using Room with SQLite that I never thought of exploring the option.

At the time, I was not aware that Realm had multiple offerings, from being used as a local database on mobile, to offering Sync features to be able to sync your app data to multiple devices.

I will pen down my experiments with MongoDB Realm as a series of articles. This is the first article in the series and it is divided into two parts.

**Part A** will explain how to create a MongoDB Realm back end for your mobile app.

**Part B** will explain how to implement Google Authentication in the
app.

>Pre-Requisites: You have created at least one app using Android Studio.

Photo by Emily Finch on Unsplash

Let's get some coffee and get the ball rolling. :)

## Part A: 

### Step 1. How to Create an Account on MongoDB Cloud

MongoDB Realm is a back end as a service. When you want to use MongoDB Realm Sync functionality, you need to create a MongoDB Realm account and it is free :D :D

> MongoDB’s Atlas offering of the database as a service is what makes this database so amazing. For mobile applications, we use Realm DB locally on the mobile device, and the local data gets synced to MongoDB Atlas on the cloud.

An account on MongoDB Cloud can be easily created by visiting
.

Once you sign-in to your account, you will be asked to create an Organization

Once you click on the Create button, you will be asked to enter organization name and select MongoDB Atlas as a Cloud Service as shown below and click Next.

Add members and permissions as desired and click on Create Organization. Since I am working on my own I added only myself as Project Owner.

Next you will be asked to create a project, name it and add members and permissions. Each permission is described on the right side. Be cautious of whom you give read/write access of your database.

Once you create a project, you will be asked to deploy your database as shown below

Depending on your use-case, you can select from given options. For this article, I will choose shared and Free service :)

Next select advance configuration options and you will be asked to select a Cloud Provider and Region

A cluster is a group of MongoDB Servers that store your data on the cloud. Depending on your app requirement, you choose one. I opted for a free cluster option for this app.

> Be mindful of the Cloud Provider and the Location you choose. Realm App is currently available only with AWS and it is recommended to have Realm App region closer to the cluster region and same Cloud Provider. So I choose the settings as shown.
> 
Give a name to your cluster. Please note this cannot be changed later.

And with this, you are all set with Step 1.

### Step 2. Security Quickstart
Once you have created your cluster, you will be asked to create a user to access data stored in Atlas. This used to be a manual step earlier but now you get the option to add details as and when you create a cluster.

These credentials can be used to connect to your cluster via MongoDB Compass or Mongo Shell but we will come to that later.

You can click on “Add My Current IP Address” to whitelist your IP address and follow as instructed.

If you need to change your settings at a later time, use Datasbase Access and Network Access from Security section that will appear on left panel.

With this Step 2 is done.
### Step 3. How to Create a Realm App on the Cloud
We have set up our cluster, so the next step is to create a Realm app and link it to it. Click on the Realm tab as shown.

You will be shown a template window that you can choose from. For this article, I will select “Build your own App”

Next you will be asked to fill details as shown. Your Data Source is the Atlas Cluster you created in Step1. If you have multiple clusters, select the one you want to link your app with.

Please note, Realm app names should have fewer than 64 characters.

For better performance, It is recommended to have local deployment and region the same or closer to your cluster region.

Check the Global Deployment section in MongoDB's official documentation for more details.

You will be shown a section of guides once you click on “Create a Realm Application”. You can choose to follow the guides if you know what you are doing, but for brevity of this article, I will close guides and this will bring you to your Realm Dashboard as shown

Please keep a note of the “App Id”. This will be needed when you create the Android Studio project.

There are plethora of cloud services that comes with MongoDB Realm. You can use functions, triggers, and other features depending on your app use cases. For this article, you will be using Authentication.

With this, you are finished with Part A. Yayyy!! :D

## Part B: 

### Step 1. Creating an Android Studio Project

I presume you all have experience creating mobile applications using Android Studio. In this step, you would "Start a new Android Project." You can enter any name of your choice and select Kotlin as the language and min API 21.

Once you create the project, you need to add dependencies for the Realm Database and Google Authentication.

**For Realm**, add this line of code in the project-level `build.gradle` file. This is the latest version at the time of writing this article.

**Edit 01:** Plugin is updated to current (may change again in future).

``` java
classpath "io.realm:realm-gradle-plugin:10.9.0"
```

After adding this, the dependencies block would look like this.

``` java
dependencies {
    classpath "com.android.tools.build:gradle:4.0.0"
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    
    classpath "io.realm:realm-gradle-plugin:10.9.0"

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
```

Now we add Realm plugin and Google Authentication in the app-level `build.gradle` file. Add this code at the top of the file but below the `kotlin-kapt` extension. If you are using Java, then this would come after the Android plugin.

``` java
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
```

In the same file, we would also add the below code to enable the Realm sync in the application. You can add it anywhere inside the Android block.

``` java
android {
...
...
realm {
    syncEnabled = true
  }
...
}
```

For Google Auth, add the following dependency in the app-level gradle file. Please note, the versions may change since the time of this article.

**Edit 02:** gms version is updated to current.

``` java
dependencies{
...
...
//Google OAuth
implementation 'com.google.android.gms:play-services-auth:20.0.1'
...
}
```

With this, we are finished with Step 1. Let's move onto the next step to implement Google Authentication in the project.

### Step 2. Adding Google Authentication to the Application

Now, I will not get into too much detail on implementing Google Authentication to the app since that will deviate from our main topic. I have listed below the set of steps I took and links I followed to implement Google Authentication in my app.

1.  Configure a Google API Console project. (Create credentials for Android Application and Web Application). Your credential screen should have 2 oAuth Client IDs.

2.  Configure Google Sign-in and the GoogleSignInClient object (in the Activity's onCreate method).
3.  Add the Google Sign-in button to the layout file.
4.  Implement Sign-in flow.

This is what the activity will look like at the end of the four steps.

>**Please note**: This is only a guideline. Your variable names and views can be different. The String server_client_id here is the web client-id you created in Google Console when you created Google Auth credentials in the Google Console Project.

``` java
class MainActivity : AppCompatActivity() {

    private lateinit var client: GoogleSignInClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestServerAuthCode(getString(R.string.server_client_id))
            .build()

        client = GoogleSignIn.getClient(this, googleSignInOptions)

        findViewById(R.id.sign_in_button).setOnClickListener{
            signIn()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(requestCode == 100){
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            val account = task.getResult(ApiException::class.java)
            handleSignInResult(account)
        }
    }

    private fun handleSignInResult(account: GoogleSignInAccount?) {
            try{
                Log.d("MainActivity", "${account?.serverAuthCode}")
                //1
                val idToken = account?.serverAuthCode

                //signed in successfully, forward credentials to MongoDB realm
                //2
                val googleCredentials = Credentials.google(idToken)
                //3
                app.loginAsync(googleCredentials){
                    if(it.isSuccess){
                        Log.d("MainActivity", "Successfully authenticated using Google OAuth")
                        //4
                        startActivity(Intent(this, SampleResult::class.java))
                    } else {
                        Log.d("MainActivity", "Failed to Log in to MongoDB Realm: ${it.error.errorMessage}")
                    }
                }
            } catch(exception: ApiException){
                Log.d("MainActivity",  exception.printStackTrace().toString())
            }
    }

    private fun signIn() {
        val signIntent = client.signInIntent
        startActivityForResult(signIntent, 100)
    }
}
```

When you run your app, your app should ask you to sign in with your Google account, and when successful, it should open SampleResult Activity. I displayed a random text to show that it works. :D

Now, we will move onto the next step and configure the Google Auth provider on the MongoDB Realm cloud account.

### Step 3. Configure Google Auth Provider on MongoRealm UI

Return to the MongoDB Realm account where you created your Realm app. On the left panel, click on the Authentication tab and you will see the list of auth providers that MongoDB Realm supports.

Click on the *edit* icon corresponding to Google Authentication provider and you will be led to a page as shown below.

**Edit 03:** Updated Screenshot as there is now a new option OpenID connect.

Toggle the **Provider Enabled** switch to **On** and enter the **Web-Client ID** and **Web Client Secret** from the Google Console Project you created above.

You can choose the Metadata Fields as per your app use case and click Save.

> Keeping old UI here as OpenID Connect is not used.
> 

With this, we are finished with Step 3. 

### Step 4. Implementing Google Auth Sync Credentials to the Project

This is the last step of Part 2. We will use the Google Auth token received upon signing in with our Google Account in the previous step to authenticate to our MongoDB Realm account.

We already added dependencies for Realm in Step 3 and we created a Realm app on the back end in Step 2. Now, we initialize Realm and use the appId (Remember I asked you to make a note of the app Id? Check Step 2. ;)) to connect back end with our mobile app.

Create a new Kotlin class that extends the application class and write the following code onto it.

``` java
val appId ="realmsignin-abyof" // Enter your own App Id here
lateinit var app: App

class RealmApp: Application() {

    override fun onCreate() {
        super.onCreate()
        Realm.init(this)

        app = App(AppConfiguration.Builder(appId).build())

    }
}
```

An "App" is the main client-side entry point for interacting with the MongoDB Realm app and all its features, so we configure it in the application subclass for getting global access to the variable.

This is the simplest way to configure it. After configuring the "App", you can add authentication, manage users, open synchronized realms, and all other functionalities that MongoDB Realm offers.

To add more details when configuring, check the MongoDB Realm Java doc.

Don't forget to add the RealmApp class or whatever name you chose to the manifest file.

``` java

    ....
    ....
    
        ...
        ...
    

```

Now come back to the `handleSignInResult()` method call in the MainActivity, and add the following code to that method.

``` java
private fun handleSignInResult(account: GoogleSignInAccount?) {
        try{
            Log.d("MainActivity", "${account?.serverAuthCode}")

            // Here, you get the serverAuthCode after signing in with your Google account.
            val idToken = account?.serverAuthCode

            // signed in successfully, forward credentials to MongoDB realm
            // In this statement, you pass the token received to ``Credentials.google()`` method to pass it to MongoDB Realm.
            val googleCredentials = Credentials.google(idToken)

            // Here, you login asynchronously by passing Google credentials to the method.
            app.loginAsync(googleCredentials){
                if(it.isSuccess){
                    Log.d("MainActivity", "Successfully authenticated using Google OAuth")

            // If successful, you navigate to another activity. This may give a red mark because you have not created SampleResult activity. Create an empty activity and name it SampleResult.
             startActivity(Intent(this, SampleResult::class.java))
                } else {
                    Log.d("MainActivity", "Failed to Log in to MongoDB Realm: ${it.error.errorMessage}")
                }
            }
        } catch(exception: ApiException){
            Log.d("MainActivity",  exception.printStackTrace().toString())
        }
}
```

Add a TextView with a Successful Login message to the SampleResult layout file.

Now, when you run your app, log in with your Google account and your SampleResult Activity with Successful Login message should be shown.

When you check the App Users section in your MongoDB Realm account, you should notice one user created.

## Wrapping Up

You can get the code for this tutorial from this GitHub repo.

Well done, everyone. We are finished with implementing Google Auth with MongoDB Realm, and I would love to know if you have any feedback for me.❤

You can post questions on MongoDB Community Forums or if you are struggling with any topic, please feel free to reach out.

In the next article, I talk about how to implement Realm Sync in your Android Application.