Advertisement
  1. Code
  2. Cloud & Hosting

Create a Note-Taking App for Android With MongoDB Stitch

Scroll to top

If you are looking for a secure serverless platform that's both feature rich and cost effective, you may want to give MongoDB Stitch a try. In addition to offering handy server-side features such as functions, service webhooks, and user authentication, it comes tightly integrated with MongoDB Atlas, a powerful and mature cloud-based data storage solution.

In this tutorial, I'll show you how to use MongoDB Stitch and a MongoDB Atlas cluster to create a note-taking app for Android from scratch. I'll also walk you through how to integrate Google Sign-In, an authentication provider supported by Stitch, into the app.

Prerequisites

To make the most of this tutorial, you'll need:

If you haven't done so already, I also suggest you go through the previous tutorial on using Stitch in your Android apps first.


1. Creating a Stitch Application

You'll need a Stitch application to be able to use services offered by the Stitch platform in your Android project. So log in to your MongoDB Atlas account and navigate to the Stitch Apps section.

Stitch home pageStitch home pageStitch home page

Press the Create New Application button. In the dialog that pops up, give a meaningful name to the application, select one of your MongoDB Atlas clusters from the dropdown list, and press the Create button.

Stitch app creation dialogStitch app creation dialogStitch app creation dialog

If you don't have any clusters currently, you can learn how to create and configure one here:

Once the application is ready, go to the Clients section and switch to the Java (Android) tab to determine what its app ID is. You'll be needing the ID later on in this tutorial.

2. Setting Up Authentication

You'll be using Google as an authentication provider for the app you'll be creating today. In other words, you'll be allowing your end users to log in to the app using their Google accounts.

From Stitch's admin console, setting up any authentication provider takes only a moment. Before you can do that, though, you have to get a few important details from the authentication provider. To get the details from Google, open a new tab in your browser, log in to your Google account, and go to the Google Cloud Platform API Dashboard.

Press the Create Project button to create a new Google Cloud project. After you give a name to the project, press the Create button.

Google project creation formGoogle project creation formGoogle project creation form

Once the project is ready, go to the Credentials section and open the OAuth consent screen tab. Here, for now, you can fill in only the Application name field and press the Save button.

OAuth consent screenOAuth consent screenOAuth consent screen

Then, press the Create credentials button, select the OAuth client ID option, and choose Android as the application type.

You'll now be prompted to enter the package name you intend to use for your Android app and an SHA-1 fingerprint. For this tutorial, I suggest you use the fingerprint of your debug certificate. To get it, open a terminal and run the following command:

1
keytool -exportcert -alias androiddebugkey \

2
-keystore ~/.android/debug.keystore \

3
-list

After you copy the fingerprint and paste it into the form, press the Create button.

OAuth client ID creation formOAuth client ID creation formOAuth client ID creation form

At this point, your Android app will be able to use Google Sign-In. However, you have to allow your Stitch application to use it too. Therefore, press the Create credentials button again. This time, choose Web application as the type of the application.

When prompted to enter an authorized redirect URI, use Stitch's callback URL: https://stitch.mongodb.com/api/client/v2.0/auth/callback

On pressing the Create button now, you'll see a pop-up containing two strings: a client ID and a client secret. Make a note of them both and go back to the Stitch admin console.

Popup showing client ID and client secretPopup showing client ID and client secretPopup showing client ID and client secret

In the Users section of the console, switch to the Providers tab and select Google. After you enable it, type in the client ID and client secret, and press the Save button.

Provider configuration screen of Stitch admin consoleProvider configuration screen of Stitch admin consoleProvider configuration screen of Stitch admin console

3. Adding a Rule

Your app's users must not be able to see each other's notes. They must only be allowed to see the notes they created themselves. To enforce this rule, go to the Rules section and press the Add Collection button.

You can now give a name to your MongoDB database and specify the name of the collection where you'll be storing all the notes. Let the name of the database be notes_db and that of the collection be notes.

Rule creation formRule creation formRule creation form

Next, select the Users can only read and write their own data rules template, which matches your app's requirements, and say that the name of the field where you'll be storing the user's authentication ID is user_id.

Rule template configuration formRule template configuration formRule template configuration form

Finally, press the Add Collection button.

If you want to take a closer look at the rule you just created, feel free to press the Advanced Mode button, which shows you a JSON equivalent of the rule.

4. Configuring an Android Project

Now that the Stitch application is ready, you can start building your Android app. So create a new Android Studio project with an empty activity, making sure that its package name matches the one you typed in earlier.

To be able to use the Stitch SDK in the project, add the following implementation dependency in the app-level build.gradle file:

1
implementation 'org.mongodb:stitch-android-sdk:4.0.5'

To support Google Sign-In, also add a dependency for Google Play services.

1
implementation 'com.google.android.gms:play-services-auth:15.0.1'

You'll be needing a few Material Design widgets, such as cards and floating action buttons, in the app. So add the following dependencies too:

1
implementation 'com.android.support:design:27.1.1'
2
implementation 'com.android.support:cardview-v7:27.1.1'
3
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'

Lastly, add your Stitch application's ID and the client ID you mentioned in the Stitch admin console as items in the strings.xml file.

1
<string name="stitch_client_app_id">YOUR_APP_ID</string>
2
<string name="google_client_id">YOUR_CLIENT_ID</string>

5. Creating Layouts

Users must only be able to use the note-taking app if they're signed in. Therefore, as soon as the app is opened, you must show them a sign-in button. The quickest way to do so is to use the SignInButton widget in the main activity's layout:

1
<com.google.android.gms.common.SignInButton
2
        android:id="@+id/sign_in_button"
3
        android:layout_width="wrap_content"
4
        android:layout_height="wrap_content"
5
        android:layout_centerInParent="true"/>

After a successful sign-in, you'll be redirecting the user to another activity containing a ListView widget, which will display the user's notes, and a FloatingActionButton widget, which the user can press to create a new note. So create another empty activity and add the following code to its layout XML file:

1
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
2
    android:layout_width="match_parent"
3
    android:layout_height="match_parent"
4
    android:padding="16dp">
5
6
    <ListView
7
        android:layout_width="match_parent"
8
        android:layout_height="match_parent"
9
        android:id="@+id/notes_container"
10
        android:dividerHeight="16dp"
11
        android:divider="@android:color/transparent"/>
12
13
    <android.support.design.widget.FloatingActionButton
14
        android:layout_width="wrap_content"
15
        android:layout_height="wrap_content"
16
        android:layout_alignParentBottom="true"
17
        android:layout_alignParentRight="true"
18
        android:src="@drawable/ic_add_black_24dp"
19
        android:id="@+id/add_note_button"
20
        android:tint="@android:color/white"/>
21
22
</RelativeLayout>

Each item of the ListView widget will be a note. To keep things simple, let's say the layout of the note only has a CardView widget containing a TextView widget. So create a new layout XML file named layout_note.xml and add the following code to it:

1
<android.support.v7.widget.CardView
2
    xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="match_parent"
4
    android:layout_height="match_parent">
5
6
    <TextView
7
        android:id="@+id/note_text"
8
        style="@style/TextAppearance.AppCompat.Body1"
9
        android:layout_width="match_parent"
10
        android:layout_height="wrap_content"
11
        android:padding="8dp" />
12
13
</android.support.v7.widget.CardView>

6. Implementing Google Sign-In

When the user presses the sign-in button, you must initiate Google's sign-in workflow. So, inside the first activity, add an on-click event handler to the button.

Inside the handler, you can go ahead and create a GoogleSignInOptions object configured to use the default sign-in options. Because your Stitch application, which can be thought of as your back-end server, must also be a part of the sign-in process, make sure you call the requestServerAuthCode() method and pass your client ID to it. The following code shows you how:

1
val signInOptions =
2
    GoogleSignInOptions.Builder(
3
        GoogleSignInOptions.DEFAULT_SIGN_IN
4
    ).requestServerAuthCode(
5
        getString(R.string.google_client_id)
6
    ).build()

You can now create a GoogleSignIn client by calling the getClient() method and passing the GoogleSignInOptions object to it as an argument. Using the client, you can easily start the sign-in workflow by getting a sign-in intent from it and passing it to the activity's startActivityForResult() method. Here's how:

1
val signInClient = GoogleSignIn.getClient(
2
        this@MainActivity, signInOptions
3
)
4
5
startActivityForResult(
6
        signInClient.signInIntent,
7
        1 // request code

8
)

To receive the result of the activity you just fired off, you must override the onActivityResult() method. Inside it, you'll have access to a new Intent object, which you can pass to the getSignedInAccountFromIntent() method to identify your user.

1
override fun onActivityResult(requestCode: Int, 
2
                              resultCode: Int, 
3
                              data: Intent?) {
4
    super.onActivityResult(requestCode, resultCode, data)
5
6
    val signedInAccount = 
7
            GoogleSignIn.getSignedInAccountFromIntent(data)
8
9
    // More code here

10
}

In case the user fails or refuses to sign in, you'll have an exception now. Handle it by displaying an informative Toast message and closing the app.

1
if(signedInAccount.exception != null) {
2
    Toast.makeText(this,
3
            "You must sign in first", Toast.LENGTH_LONG).show()
4
    finish()
5
    return
6
}

In case of a successful sign-in, however, you'll have access to a server authentication code you can use to create a GoogleCredential object. By passing the object to the loginWithCredential() method of your project's default Stitch client, you can both register and log the user in to your app.

Once the method completes successfully, the app should switch to the second activity, which has the user interface elements to display notes and add new notes. The following code shows you how to do so concisely:

1
Stitch.getDefaultAppClient().auth
2
    .loginWithCredential(
3
        GoogleCredential(signedInAccount.result.serverAuthCode)
4
    )
5
    .addOnSuccessListener {
6
        // Open activity that shows the notes

7
        startActivity(
8
            Intent(this@MainActivity,
9
                    NotesActivity::class.java
10
            )
11
        )
12
    }

If you build and run the app now, you should be able to use one of your Google accounts to log in to it.

App showing sign in screensApp showing sign in screensApp showing sign in screens

7. Adding Notes

In the second activity, you'll need both a Stitch client and a MongoDB Atlas client. You'll need the former to get the authentication ID of the user, and the latter to perform read and write operations on your MongoDB Atlas cluster. So add them both as private fields of the activity.

1
private val stitchClient = Stitch.getDefaultAppClient()
2
3
private val atlasClient  = stitchClient.getServiceClient(
4
                                RemoteMongoClient.factory,
5
                                "mongodb-atlas"
6
                          )

When users press the floating action button, you must display a dialog that prompts them to type in their notes. With the Material Dialogs library, which you added as a dependency earlier, doing so is very intuitive.

The following code shows you how to add an on-click listener to the button and create a basic input dialog:

1
add_note_button.setOnClickListener {
2
    val dialog = MaterialDialog.Builder(this@NotesActivity)
3
            .title("New Note")
4
            .input("Type something", null, false,
5
                { _, note ->
6
7
                    // More code here

8
9
                }
10
            ).build()
11
    dialog.show()
12
}

Inside the event handler of the dialog, you'll have access to the note the user typed in. To store it in your MongoDB Atlas cluster, you must put it inside a new MongoDB document. Additionally, to make sure that the note is visible only to the user who created it, the document must include a user_id field whose value matches the authentication ID of the user. The following code, which goes inside the event handler, shows you how to create the document:

1
val document = Document()
2
document["text"] = note.toString()
3
document["user_id"] = stitchClient.auth.user!!.id

Now that the document is ready, you must insert it into the notes collection, which belongs to the notes_db database. Here's how you can get references to the database and the collection, and use the insertOne() method to insert the document:

1
val collection = atlasClient.getDatabase("notes_db")
2
                            .getCollection("notes")
3
4
collection.insertOne(document).addOnSuccessListener {
5
    Toast.makeText(this@NotesActivity,
6
            "One note saved", Toast.LENGTH_LONG).show()
7
}

If you run the app now, you should be able to create new notes and save them.

App showing input dialogApp showing input dialogApp showing input dialog

8. Displaying Notes

To be able to display the notes that a user has created, you must first fetch all the documents in the notes collection that belong to the user. You don't have to write a complex query to do that, though. Because of the rule you created earlier, Stitch automatically ensures that any query you run on the collection will return only those documents the user owns.

Create a new method to display the notes.

1
private fun showNotes() {
2
    // More code here

3
}

Inside the method, you can directly call the find() method on the notes collection to create a query that can fetch the user's notes. To execute the query asynchronously, you must then call the into() method and pass an empty list to it. The results of the query will be available in the list once it completes successfully.

1
val notes = mutableListOf<Document>()
2
3
atlasClient.getDatabase("notes_db")
4
        .getCollection("notes")
5
        .find()
6
        .into(notes)
7
        .addOnSuccessListener {
8
            
9
            // More code here

10
11
        }

Inside the on-success listener, you must now create an instance of the ArrayAdapter class to render the list of notes. However, you can't pass a list of Document objects directly to the constructor of the class. You must first convert it into a list of String objects. The following code shows you how to do so using the map() method:

1
val adapter = ArrayAdapter<String>(this@NotesActivity,
2
        R.layout.layout_note, R.id.note_text,
3
        notes.map {
4
            it.getString("text") // Extract only the 'text' field

5
                                // of each document

6
        }
7
)

Once the adapter is ready, you can put it to work by assigning it to the adapter property of the ListView widget.

1
notes_container.adapter = adapter

The showNotes() method is now ready. Add a call to it inside the onCreate() method so that the users can see their notes as soon as the activity is opened. Furthermore, if you want the list to display new notes as soon as they are created, I suggest you also add a call to it inside the on-success listener you attached to the insertOne() method.

With the above changes, if you run the app again, you'll be able to both add new notes and view existing ones.

App displaying notesApp displaying notesApp displaying notes

Conclusion

In this tutorial, you saw how easy it is to create a simple mobile app backed by MongoDB Stitch. You also learned how to keep your end users' data secure and private using Google as an authentication provider and Stitch's declarative access rules.

To learn more about MongoDB Stitch, do refer to its comprehensive official documentation.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
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.