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:
- Android Studio 3.1 or higher
- a MongoDB Atlas account
- a device or emulator running Android 5.0 or higher
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.
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.
If you don’t have any clusters currently, you can learn how to create and configure one here:
-
MongoDBCreate a Database Cluster in the Cloud With MongoDB Atlas
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.
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.
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:
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list
After you copy the fingerprint and paste it into the form, press the Create button.
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.
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.
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.
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.
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:
implementation 'org.mongodb:stitch-android-sdk:4.0.5'
To support Google Sign-In, also add a dependency for Google Play services.
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:
implementation 'com.android.support:design:27.1.1' implementation 'com.android.support:cardview-v7:27.1.1' 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.
YOUR_APP_ID YOUR_CLIENT_ID
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:
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:
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:
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:
val signInOptions = GoogleSignInOptions.Builder( GoogleSignInOptions.DEFAULT_SIGN_IN ).requestServerAuthCode( getString(R.string.google_client_id) ).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:
val signInClient = GoogleSignIn.getClient( this@MainActivity, signInOptions ) startActivityForResult( signInClient.signInIntent, 1 // request code )
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.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) val signedInAccount = GoogleSignIn.getSignedInAccountFromIntent(data) // More code here }
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.
if(signedInAccount.exception != null) { Toast.makeText(this, "You must sign in first", Toast.LENGTH_LONG).show() finish() return }
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:
Stitch.getDefaultAppClient().auth .loginWithCredential( GoogleCredential(signedInAccount.result.serverAuthCode) ) .addOnSuccessListener { // Open activity that shows the notes startActivity( Intent(this@MainActivity, NotesActivity::class.java ) ) }
If you build and run the app now, you should be able to use one of your Google accounts to log in to it.
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.
private val stitchClient = Stitch.getDefaultAppClient() private val atlasClient = stitchClient.getServiceClient( RemoteMongoClient.factory, "mongodb-atlas" )
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:
add_note_button.setOnClickListener { val dialog = MaterialDialog.Builder(this@NotesActivity) .title("New Note") .input("Type something", null, false, { _, note -> // More code here } ).build() dialog.show() }
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:
val document = Document() document["text"] = note.toString() 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:
val collection = atlasClient.getDatabase("notes_db") .getCollection("notes") collection.insertOne(document).addOnSuccessListener { Toast.makeText(this@NotesActivity, "One note saved", Toast.LENGTH_LONG).show() }
If you run the app now, you should be able to create new notes and save them.
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.
private fun showNotes() { // More code here }
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.
val notes = mutableListOf() atlasClient.getDatabase("notes_db") .getCollection("notes") .find() .into(notes) .addOnSuccessListener { // More code here }
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:
val adapter = ArrayAdapter(this@NotesActivity, R.layout.layout_note, R.id.note_text, notes.map { it.getString("text") // Extract only the 'text' field // of each document } )
Once the adapter is ready, you can put it to work by assigning it to the adapter
property of the ListView
widget.
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.
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.
Powered by WPeMatico