Navigation

Set Up the Task Tracker Tutorial Backend

Prerequisites

Before you get started, you’ll need a MongoDB Atlas account and cluster. For details on how to create an account and set up a free M0 cluster, see Get Started with Atlas.

MongoDB Version 4.4 Required

In order to use Realm Sync, your Atlas cluster must use MongoDB version 4.4. When setting up your cluster, select MongoDB 4.4 from the dropdown menu under Additional Settings.

A. Create a MongoDB Realm App

To begin, you need to create a new Realm app. A Realm app is a central, server-side configuration that functions as the backend for your application.

1

Start Creating a New App

In MongoDB Atlas, navigate to the project that you want to create the app in. Once in your project, click the Realm tab in the top navigation and then click Create a New App.

../../_images/task-tracker-web-create-new-app.png
2

Name the App

Enter a name for your application. In this tutorial we’ll use the name task-tracker-tutorial, but you can choose another name if you prefer to. Realm app names must be alphanumeric and have fewer than 64 characters.

../../_images/task-tracker-web-name-your-application.png
3
4

Create the App

Click Create Realm Application. Realm will create your new app and automatically redirect you to the app’s dashboard.

B. Define Your Data Model

In MongoDB Realm, all data conforms to schemas that you define. The types described by these schemas make up your app’s data model and are a key part of data access and security. Realm uses your data model to generate GraphQL types and operations as well as to validate reads and writes.

1

Set Up the MongoDB Collections

You define the schemas for all data in your application as rules for collections in a linked MongoDB Atlas cluster. To define rules for a collection, you first need to make the collection available to your Realm app.

For this app, we’ll use three collections: projects, users, and tasks.

Click Rules in the lefthand navigation to navigate to the rules editor. In the left sidebar of the rules editor, find the name of your linked cluster and click the plus button next to it. Realm will prompt you to add a new collection.

For Database Name, enter tracker and for Collection Name, enter tasks. We’ll define our own permissions in a bit, so don’t select any permissions template. Click Add Collection to finish setting up the tracker.tasks collection.

Once complete, repeat this process to set up the tracker.users and tracker.projects collections as well.

../../_images/task-tracker-web-setup-collections.png
2

Define a Schema for Project Documents

We want to group related tasks together into a single project. To do this, we can store metadata for each project in the tracker.projects collection and indicate the project that each task belongs to in the task document.

In the rules editor, select the tracker.projects collection and then click the Schema tab. Paste in the following schema and then click Save.

{
  "title": "Project",
  "bsonType": "object",
  "required": [
    "_id",
    "name"
  ],
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "_partition": {
      "bsonType": "string"
    },
    "name": {
      "bsonType": "string"
    }
  }
}

Sync Rules

In this project, we primarily use projects to handle security for mobile applications using sync. Task and User documents include a project name as their partition key which allows us to sync tasks for all of a user’s projects.

Data access permissions work differently for synced and non-synced clusters, so you won’t use these partition keys if you only connect through the GraphQL API.

3

Define a Schema for User Documents

We want to store some information for each user of the app in the tracker.users collection, such as their name and avatar image. These documents are separate from Realm’s internal user objects, so we’ll also store each user’s ID value in the _id field of their document. This lets us identify which document describes a given user later when we want to access their information. To codify this, we’ll use a schema that defines the shape and contents of user documents.

In the rules editor, select the tracker.users collection and then click the Schema tab. Paste in the following schema and then click Save.

{
  "title": "User",
  "bsonType": "object",
  "required": [
    "_id",
    "name"
  ],
  "properties": {
    "_id": {
      "bsonType": "string"
    },
    "name": {
      "bsonType": "string"
    },
    "image": {
      "bsonType": "string"
    }
  }
}
4

Define a Schema for Task Documents

The core function of a task tracker is to store data about a user’s tasks. In this app, we store the task data as documents in the tracker.tasks collection. Each task has a descriptive name and can have one of three statuses: Open, In Progress, or Closed. Additionally, each task may specify a specific user as its assignee. We’ll use another schema to define the shape and contents of documents in the tasks collection.

In the rules editor, select the tracker.tasks collection and then click the Schema tab. Paste in the following schema and then click Save.

{
  "title": "Task",
  "bsonType": "object",
  "required": [
    "_id",
    "name",
    "status"
  ],
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "_partition": {
      "bsonType": "string"
    },
    "assignee": {
      "bsonType": "string"
    },
    "name": {
      "bsonType": "string"
    },
    "status": {
      "bsonType": "string"
    }
  }
}
5

Define a Relationship Between Tasks and Users

The assignee field of each task contains the user id string of the user that the task is assigned to. We can use this information to define a relationship between documents in the tasks and users collections. This will allow us to write GraphQL operations that can read and modify related documents as if they were a single document.

To define the relationship, ensure you’re editing rules for the tracker.tasks collection and then click the Relationships tab. Click Add a Relationship and define a relationship that points from the assignee property to the _id property in the tracker.users collection.

{
  "assignee": {
    "foreign_key": "_id",
    "ref": "#/relationship/mongodb-atlas/tracker/users",
    "is_list": false
  }
}
../../_images/task-tracker-web-add-relationship.png

C. Configure User Authentication

Every request sent to Realm must come from an authenticated user, so we need to have a way for users to create accounts and log in. For this app, we’ll use email/password authentication. Authenticating users has the additional benefit of giving each user a persistent identity that we can associate with their tasks in order to easily find and secure them.

1
2

Enable the Provider

Set the Provider Enabled toggle to on.

../../_images/task-tracker-web-auth-enable.png
3

Configure User Confirmation

For the User Confirmation Method, select Automatically confirm users. As the name suggests, this method automatically confirms new users when they register with a valid email and password.

../../_images/task-tracker-web-auth-confirm.png

Exercise: Support Email Confirmation

Once you’ve finished building the application, consider modifying the app to require new users to confirm their accounts before they log in. To learn how, check out the docs for user confirmation.

4

Configure Password Resets

For the Password Reset Method, select Run a password reset function. This method enables an SDK method that calls a Realm Function to handle the password reset. In this tutorial we won’t worry about password resets, so you can use the default password reset function, resetFunc, which denies all password reset requests.

../../_images/task-tracker-web-auth-reset.png

Exercise: Support Password Resets

Once you’ve finished building the application, consider modifying the app to allow users to reset their passwords. To learn how, check out the docs for password resets.

D. Define an Authentication Trigger

We want each user to have a corresponding document in the users collection that contains their information. We could create these documents manually for every user, but that approach is prone to errors and adds complexity to your client applications. Instead, we can use a trigger to automatically add a document for each user when they register their account.

1

Create a New Trigger

To define a new trigger, click Triggers in the lefthand navigation and then click Add a Trigger.

../../_images/task-tracker-web-add-trigger.png
2

Define the Trigger Type

Set the Trigger Type to Authentication and give the trigger a descriptive name. We suggest onNewUser, but you can use any name you like.

../../_images/task-tracker-web-configure-trigger-type.png
3

Configure the Trigger Action

We want the trigger to fire when users register a new account, so set the Action Type to Create. We’re using email/password authentication for this app, so specify Email/Password as the only Provider.

../../_images/task-tracker-web-configure-trigger-event.png
4

Define the Trigger Function

When a new user registers their account, we want to add a document to the tracker.users collection that describes the user. To do that, we’ll use a function that can access the user’s info and inserts a new document for them. The _id of each user document should contain the user’s ID value so that we can map the document to the user.

Create a new function named createNewUserDocument and paste in the following code:

exports = async function createNewUserDocument({ user }) {
  const cluster = context.services.get("mongodb-atlas");
  const users = cluster.db("tracker").collection("users");
  return await users.insertOne({
    _id: user.id,
    _partition: "My Project",
    name: user.data.email,
  });
};

E. Deploy Your App

At this point your Realm App is fully configured and almost ready to accept requests from client applications. All that’s left to do is to deploy the fully configured app.

Click Deploy in the lefthand navigation and find the current draft at the top of the deployment history table. Click the Review & Deploy Changes button and review the diff to make sure that everything looks correct. When you’re ready to go live, click Deploy.

../../_images/task-tracker-web-deploy-history.png

What’s Next?

You just built a functional task tracker application backend with MongoDB Realm. Great job!

Now that you have a working Realm application, you can follow one of our client application tutorials to connect to your Realm app and manage tasks from a mobile or web application.