Реалистичный Realm. 1 год опыта
Realm давно известен в среде мобильных (и не только) разработчиков. К сожалению, в рунете почти нет статей об этой базе данных. Давайте исправим эту ситуацию.
Год назад в build.gradle нашего проекта появилась строчка:
За этот год код Realm вырос до версии 3.3, обзавелся множеством фич и починил кучу багов, реализовал новый функционал и получил облачный бекенд. Давайте поподробнее поговорим о Realm в реалиях Andoroid разработки и обсудим тонкие моменты, возникающие при его использовании.
О нас
Realm как стартап
Realm как база данных
The Realm Mobile Platform is a next-generation data layer for applications. Realm is reactive, concurrent, and lightweight, allowing you to work with live, native objects.
Если кратко, то это нативная no-sql база данных для Android (Java, Kotlin), iOS (Objective-C, Swift), Xamarin (C#) и JavaScript (React Native, Node.js).
Так же есть backend, который позволяет синхронизировать данные из всех источников.
Из ключевых особенностей стоит отметить zero copy, MVCC и ACID. Встроенного механизма устаревания и очистки данных нет.
Hello world
Hello world под Android выглядит следующим образом:
Добавим в build.gradle
В Application настроим Realm Configuration
И можно начинать работать с базой данных:
Сравнение с другими базами данных
На хабре есть статья от 8 апреля 2016 года, где сравниваются 9 ORM под Android, в том числе Realm. Realm там в лидерах, вот графики:
На своем сайте Realm приводит следующую статистику:
Live Objects
Все объекты из Realm можно получить синхронно или асинхронно.
Синхронное чтение
Вызываем метод Realm и блокируем поток, пока не получим объект или null. Использовать объекты, полученные в других потоках, нельзя, поэтому для использования в главном потоке, нужно блокировать ui или использовать асинхронные запросы. К счастью, Realm предоставляет нам прокси, а не сам объект, поэтому все происходит достаточно быстро. С объектом можно работать сразу после получения.
Асинхронное чтение
Весьма неочевидный кейс. Как вы думаете, что произойдет в этом коде:
Правильный ответ: получим ошибку java.lang.IllegalStateException
При асинхронном чтении мы хоть и получаем объект сразу, но работать с ним не можем, пока он не загрузится. Проверять это нужно с помощью функции isLoaded() или вызвать блокирующую функцию load(). Выглядит достаточно неудобно, поэтому тут лучше использовать rx. Преобразуем в observable и получаем загруженный объект в OnNext. Асинхронные операции доступны только в потоках с Looper.
Основные особенности Realm объектов
Транзакции
Изменять привязанные к Realm объекты можно только внутри транзакции, при изменении вне транзакции получим ошибку. С одной стороны, не очень удобно, с другой стороны — дисциплинирует и не дает изменять объекты в любой части кода, только в определенном слое (database). Также нужно помнить, что транзакции внутри другой транзакции запрещены.
Транзакции можно производить синхронно и асинхронно. Давайте подробнее рассмотрим каждый из вариантов:
Синхронные транзакции:
Также можно выполнять транзакции между beginTransaction и commitTransaction, однако рекомендуется использовать именно executeTransaction.
К сожалению, синхронные транзакции не поддерживают onError callback, так что обработка ошибок остается на вашей совести. Есть issue на добавление onError callback c июня 2016 года.
Асинхронные транзакции
Асинхронные транзакции запускаются методом asyncTransaction. На вход отдаем саму transaction и callback onSuccess и onError, на выходе получаем объект RealmAsyncTask, с помощью которого мы можем проверить статус или отменить транзакцию. Асинхронные транзакции запускаются только в тредах с Looper. Пример асинхронной транзакции:
Пара важных нюансов:
Вы не сможете присвоить через сеттер объект, не привязанный к Realm. Необходимо сначала положить объект в базу, а потом прикрепить привязанную копию. Пример:
Много транзакций лучше объединять в одну. В Realm есть внутренняя очередь на транзакции (размером 100) и если вы превысите ее, упадет исключение.
Все асинхронные транзакции работают на одном executor’e
Если у вас будет много асинхронных операций за короткое время, получите ошибку RejectedExecutionException. Выходом из данной ситуации будет использование отдельного потока и запуск в нем синхронных транзакций или объединение нескольких транзакций в одну.
Open / close realm
Все объекты из базы данных мы получаем, используя конкретный instance Realm-a, и можем работать с ними пока открыт этот instance. Как только мы вызовем realm.close(), любая попытка чтения объекта обернется для нас исключением. Если мы не будем вовремя закрывать Realm, то это приведет к утечкам памяти, т.к. сборщик мусора не умеет корректно работать с ресурсами, используемыми Realm.
В официальной документации рекомендуется открывать / закрывать Realm:
Для чтение объектов с помощью Rx можно использовать “изолированные” instance и закрывать их в doOnUnsubscribe (или использовать Observable.using)
Также есть особенность, связанная с закрытием Realm в onDestroy\onDestroyView. Иногда после закрытия Realm происходит вызов FragmentManagerImpl.moveToState → ViewGroup.removeView →… → RecyclerViewAdapter.getItemCount() и вызывается метод list.size() от невалидной коллекции. Так что тут нужно проверять isValid() или отвязывать adapter от recyclerView
Если вы используете Kotlin Android Extensions, то работать с view (из kotlinx.android.synthetic.*) из Fragment можно только начиная с метода onViewCreated(), лучше настраивать все listeners в этом методе, чтобы не получить NPE.
После разбора трех самых важных особенностей, пробежимся по менее важным:
Notifications, RxJava
Realm поддерживает уведомления об изменении данных, причем как самого объекта, так и вложенных объектов (всех залинкованных объектов). Реализовано это с помощью RealmChangeListener (нам приходит сам объект), RealmObjectChangeListener ( приходит измененный объект и ObjectChangeSet для него, можно понять какие поля изменились) или с помощью RxJava (в onNext получаем объект, в случае асинхронного запроса необходимо проверять isLoaded(), работает только в потоках с Looper).
RxJava2 пока не завезли, issue висит с сентября 2016 года, когда реализуют — неизвестно, используйте Interop.
Аналогично можно слушать изменения коллекций или всего instance Realm. Слушать изменения внутри транзакций запрещено.
Многопоточность и асинхронность
“Управление параллельным доступом с помощью многоверсионности (англ. MVCC — MultiVersion Concurrency Control) — один из механизмов обеспечения параллельного доступа к БД, заключающийся в предоставлении каждому пользователю так называемого «снимка» БД, обладающего тем свойством, что вносимые пользователем изменения в БД невидимы другим пользователям до момента фиксации транзакции. Этот способ управления позволяет добиться того, что пишущие транзакции не блокируют читающих, и читающие транзакции не блокируют пишущих.”
На практике это выглядит следующим образом: мы можем слушать изменения объекта или с помощью RxJava получать измененные объекты в onNext. В случае, если изменения происходят в потоке А, а мы работаем с объектом в потоке B, то поток B узнает об изменениях после закрытия Realm instance в потоке A. Изменения передаются посредством Looper. Если в потоке B Looper-a нет, то изменения не дойдут (можно проверить методом isAutoRefresh()). Выход из данной ситуации — использовать метод waitForChange().
Что касается асинхронных вызовов и транзакций, то их лучше не использовать вовсе. Удобнее переводить действия на отдельный поток и там выполнять синхронные операции. Причин несколько:
Тестирование
Один Realm хорошо, а три лучше
Работая с Realm мы всегда имеем ввиду стандартный realm, однако существуют еще In-Memory Realm и Dynamic Realm.
Стандартный Realm — можно получить методами Realm.getDefaultInstance() или с помощью конкретной конфигурации Realm.getInstance(config), конфигураций может быть неограниченное количество, это по сути отдельные базы данных.
In-Memory Realm — это Realm, который все записанные данные хранит в памяти, не записывая их на диск. Как только мы закроем этот instance, все данные пропадут. Подходит для кратковременного хранения данных.
Dynamic Realm — используется в основном при миграции, позволяет работать с realm — объектами без использования сгенерированных классов RealmObject, доступ осуществляется по именам полей.
Наследование и полиморфизм
Kotlin
Realm mobile platform

Отладка
Для отладки у нас есть несколько инструментов:
Архитектура
Realm отлично подходит для MV* архитектур, когда вся реализация прячется за интерфейсом базы данных. Все обращения и выборки происходят в модуле базы данных (repository), наверх отдаются Observable c автоматически закрываемым realm при unsubscribe. Или принимаем на вход instance realm и производим все действия с ним. При записи объектов мы открываем realm, записываем данные и закрываем его, на вход подается только объект для сохранения. Оба примера смотрите на github.
Увы, использование Realm (без copyFromRealm) накладывает серьезные ограничения на использование clean architecture. Использовать разные модели данных для разных слоев не получится, пропадает весь смысл live объектов и прокси списков. Также сложности возникнут при создании независимых слоев и открытии\закрытии Realm, тк эта операция привязана к жизненному циклу Activity\Fragment. Хорошим вариантом будет изолированный слой получения данных, преобразование объектов и сохранение их в базе данных.
Realm очень удобен при построении offline-first приложений, когда все данные для отображения мы получаем из базы данных.
Полезные ссылки
Для продолжения знакомства и разбора тонких моментов, рекомендуем следующие статьи:
MongoDB Atlas OverviewВ¶
OverviewВ¶
MongoDB Realm provides a first-class service interface for MongoDB Atlas that enables secure querying of one or more Atlas data sources. You can use the Query API syntax to access your data directly in your client application code or from a Realm Function.
The MongoDB service secures your data with a dynamic, role-based Rules engine that proxies and modifies incoming queries based on rules that you define. There are three types of MongoDB collection rules: roles, filters, and schemas.
Get StartedВ¶
To get started with the MongoDB service, link a data source to your application and define roles and permissions for a collection. After you’ve created at least one role, you can start to work with data in the collection.
CRUD & Aggregation OperationsВ¶
MongoDB Realm allows you to securely work with data in a MongoDB Atlas cluster directly from your client applications and Functions using standard, platform-idiomatic MongoDB query syntax. You can also access a linked MongoDB Atlas Data Lake from a system function.
The following guides demonstrate how to use MongoDB service actions to work with data in a linked data source:
When working with a linked MongoDB Atlas cluster outside of a system function, MongoDB Realm dynamically determines which documents and fields in a collection each application user can read and write for all incoming query operations by evaluating collection rules that you define.
If you do not define rules for a collection, queries on the collection will fail.
MongoDB Realm does not support all MongoDB CRUD and Aggregation operations when you query MongoDB as a specific user. You can bypass this limitation by querying MongoDB from a system function that runs as the system user, which has access to the full MongoDB CRUD and Aggregation APIs.
For more information on which operations are unsupported, see CRUD & Aggregation APIs.
ConsiderationsВ¶
System-Generated Cluster UsersВ¶
MongoDB Realm automatically creates a MongoDB user for each app linked to a cluster. These users are for internal use only and cannot be edited or manually deleted. If you delete a Realm app, the associated user will also be deleted.
Users generated by MongoDB Realm have names of the form: mongodb-realm-
Accessing Application Data with Another ToolВ¶
MongoDB Realm connects to standard MongoDB Atlas clusters, which means that you can connect directly to a linked cluster using another tool such as the mongo shell or MongoDB Compass. There are no special considerations when reading data from a linked cluster with another tool.
For example, if you are using the mongo shell to update documents in the products collection, your command might resemble the following code:
Realm Sync Schema Data ConsistencyВ¶
If the collection in which you create and modify objects is also accessed by Realm Sync clients, you must ensure that the data conforms to the Realm object schema defined on the collection. Consider the following scenario:
You have a collection of objects that is used by Realm Sync clients. The object schema for the collection looks like this:
The same scenario holds true if a valid document is modified outside of Realm Sync such that one or more properties no longer conform to the Sync schema.
MongoDB Realm Application ServicesВ¶
MongoDB Realm provides a suite of managed cloud services including Realm Sync, serverless cloud functions, declarative data access rules, and more. You can use Realm’s services to write and host a full application in a managed cloud environment backed by MongoDB Atlas.
Create a New Realm App
Realm Apps contain all of your hosted services. Learn how to set up your Atlas cluster and create a new serverless application.
Build a Synced Task Tracker
Build a Web Task Tracker with GraphQL
Follow a tutorial to build a real-time task tracker web app.
Build a Serverless App Backend
See how to use HTTPS endpoints and triggers to run a serverless GitHub issue tracker.
Application services have usage-based billing and include a generous monthly free tier for small development and production apps, so you can get started at no cost. For more details, see Billing.
Explore MongoDB Realm ServicesВ¶
Realm Sync
Automatically synchronize data stored in Realm Database across devices and users.
User Authentication
Configure one or more authentication providers that let users log in to your application.
Functions
Write serverless JavaScript code to handle your application logic in the cloud.
Schemas & Rules
Define data types, control what users can read and write, and validate data changes.
Triggers
Run functions that automatically execute for events like data changes or at scheduled times.
HTTPS Endpoints
Define HTTP endpoints for third-party apps and services to call.
GraphQL
Access your data with an automatically generated GraphQL API and write custom query and mutation resolvers.
Static File Hosting
Host and publish static assets like images or source files for a website on Realm’s CDN.
Build and Deploy an AppВ¶
You can use any of the following interfaces to work with Realm application services:
Introduction to MongoDB Realm for Mobile DevelopersВ¶
This introduction explains the MongoDB Realm product for mobile application developers. After reading, you should understand:
If you prefer working on the backend or on web applications, consider reading the Introduction for Web Developers or the Introduction for Back-end Developers.
What Problem Does MongoDB Realm Solve?В¶
Mobile developers face a number of unique challenges. You must:
All of these challenges present different obstacles. You can solve each in isolation with a wide variety of libraries and frameworks. Deciding the right solution for each problem with the right tradeoffs is a challenge mobile developers know all too well.
The combination of multiple environments creates even more challenges. For instance, you can use a Java library on your Android client to serialize objects, but that library likely wouldn’t work on iOS. And this doesn’t even take into account consistency across backend services.
Realm DatabaseВ¶
Many of these challenges arise due to particularities of the mobile environment. These challenges include network reliability, local storage, and keeping UIs reactive. Realm Database solves many common mobile programming headaches:
The Realm SDK lets you connect to local realms for Android, iOS, Node.js, React Native, and UWP development.
MongoDB AtlasВ¶
Client applications generate a lot of data. Whether it’s uploaded reviews and ratings, posts and comments on a blog, or inventory in a kitchen, you need to store that data somewhere. MongoDB Atlas provides cloud-hosted managed instances of MongoDB that are always available.
Atlas supports aggregations and other complex workloads with the full capabilities of MongoDB. You can connect to your Atlas instance in your backend services using MongoDB drivers for a wide range of languages. Or connect your Atlas instance to MongoDB Charts to visualize your data in real time. Storing your data in Atlas makes it easy to share data across users and platforms.
MongoDB RealmВ¶
MongoDB Realm also provides services to fulfill several common application backend requirements:
Get Started with MongoDB RealmВ¶
Jump right in and create a MongoDB Realm application or check out our Task Tracker tutorial for any of these platforms:
You can also refer to the documentation for each client SDK:
SummaryВ¶
Live Objects and Realm Sync offer significant benefits over traditional mobile development stacks:
How to Integrate MongoDB Realm with React: Part 1
In this tutorial, we’ll learn how to create a MongoDB Realm application and integrate it with React
Shahed Nasser
Read more posts by this author.

Shahed Nasser
You can read part 2 here.
MongoDB Realm is a serverless backend that allows you to not only write and read data easily but also provides easy ways to authenticate users, keep your data synchronized across multiple devices, and more.
In this tutorial, we’ll learn how to create a MongoDB Realm application, add sample data to it, restrict data access based on user roles, then how to integrate the application with React. We’ll create a website that shows restaurant reviews and allows users to create an account and add their own reviews.
You can find the code for this tutorial here.
Create a MongoDB Realm App
Create a MongoDB Cluster
Before we can create a MongoDB Realm App, we need to create a MongoDB Cluster. To do that, go to the Atlas portal. If you don’t have an account or you’re not already logged in, you need to do that first.
If you’re not redirected to the Projects page, click on the logo at the top left.
Once you’re on the Projects page, click on the New Project button at the right.
Then you will be asked to enter a project name. You can name it whatever you want. After that, you’ll be asked to add members, if you need to. Once done, click on Create Project.
Once the project is created, you will be redirected to the Clusters page. Click on «Build a Cluster»
You’ll be asked to pick a cluster plan. For this tutorial, you can just choose the free plan.
Then after that you can just click on «Create Cluster»
After this, your cluster will take some time to deploy. You need to wait until it’s created and deploy, which can take a couple of minutes.
The next step will be to add a sample dataset to our Cluster. If you already have a dataset, you can add your own data instead.
To start adding data, click on Collections in the Cluster you created.
Then, click on Load a Sample Dataset.
A popup window will open to ask for confirmation. Once you confirm, a sample dataset will be installed in your cluster. This dataset contains a bunch of useful databases and collections for different use cases.
It will take a minute or two to finish installing the sample dataset. Once it’s done, you’ll see that now you have a few databases now.
We’ll only be using the sample_restaurants database, so you can go ahead and delete the rest by clicking on the trash icon that appears when you hover a database name.
Now that our MongoDB Cluster is ready, let’s go ahead and create a MongoDB Realm App.
Create a MongoDB Realm App
To go to MongoDB Realm, click on «Realm» in the tab bar next to «Atlas»
A dialog will show to start creating MongoDB Realm App. You’ll need to enter a name for the Realm Application which can be whatever you want. Then, you’ll need to choose a cluster to link the Realm App to. You’ll need to choose the cluster we just created. Once you do that, click on Create Realm Application.
Next, we’ll need to choose a collection from the cluster to add access to from the Realm app. To do that, click on Get Started under Add a Collection on the dashboard.
Next, we need to select a permission template. Permission templates allow to easily restrict read and write access as necessary.
In the website we’re creating, all users can read all data about restaurants, and they can write reviews in their own account.
For now, we’ll just choose «Users can only read all data» from the dropdown. Once you’re done, click «Add Collection.» Next, click on neighborhoods from the sidebar and choose the same template then Add Collection.
Every time you make changes to the Realm App, you have to deploy it for changes to take effect. To deploy the changes we just made, click on «Review Draft & Deploy» in the blue banner at the top.
And that’s it! We created a Realm App that’s linked to our cluster and the collections in it. This will provide a serverless backend that allows us to retrieve and write data to our cluster easily.
Generate Schemas
To be able to query our collections and documents, and to be able to apply certain roles, permissions and restrictions, we need to generate Schema definitions for each of the collections. To do that, click on Schema in the sidebar.
Then, click on Generate Schema button. This will generate the schema based on the data that’s already in the collection.
Under «Generate schema(s) for:» choose «all unconfigured collections» and for Sample type in «20» as we don’t need to sample so many documents considering our data is simple. Then, click on Generate Schema.
Once it’s done, you’ll see the Schema generated with all the fields and their respective types.
Setup Authentication in Realm App
In our Realm app, we’ll be using two Authentication providers:
This means that users have permission to read all data, but only write their own data.
In the Realm Portal, click on Authentication in the sidebar. You’ll see a few Authentication providers that are all disabled.
We’ll first enable «Allow users to login anonymously.» Click on the edit button for this one and just toggle it on.
Then go back to the Authentication page. We’ll now click on Edit for the second one which is «Email/Password.»
First, enable the provider. Next, for «User Confirmation Method,» choose «Automatically confirm users.» MongoDB Realm provides a user confirmation workflow for your app, but in our case we don’t need it.
Next comes «Password Reset Method.» MongoDB Realm also provides a password reset method for your users. We won’t be implementing it, but because we need to enter the configuration, just enter http://example.com/reset in «Password Reset URL.»
Once you’re done, click Save. Our users are now able to login with an email and password.
The last step for setting up authentications is to allow users who are logged in with email and password to write their own reviews. To do that, go to rules in the sidebar, then choose the restaurants collection, then click on «New Role» in the table.
A popup will open. You first need to enter the role name. We’ll name it «Users»
Next, we’ll need to enter «Apply When» condition, which means when should the user be considered as part of this role. We want users who are logged in with their email and password to be able to write their reviews. Enter the following:
Then, for the «Document-Level Permissions» choose «Insert Documents.» Once you’re done, click «Done Editing.»
Then, in the table click «Add Field» and type in «grades» and click the checkmark. Then check for both Read and Write for the User role. This adds the double restriction which is users are only able to write in grades, nothing else. As for Read, you can check for all fields. Then, click on the left Arrow under the «User» role name to give the User role a higher priority when matching the logged in user with the correct role. Once you’re done, click on Save. The table should look like this:
And with this done, we can now anonymous and logged in users can read all data, but only users logged in can write their own reviews.
One last thing to do is make sure to click on Review Draft & Deploy for all the changes to take effect.
Now, we have our MongoDB Realm app ready for integration with React. Next, we’ll go over how to integrate it with React and use all the functionalities we’ve been setting up.
React Setup
In case you don’t have a React project ready, run the following to create one:
Next, we’ll install the MongoDB Realm Web SDK:
That’s all we need to start using Realm with React. We’ll also install React Bootstrap to make styling easier:
and React Router to add different pages:
Home Page
Let’s first start by modifying creating the Home component which will be the home page. The home page will just show a list of restaurants and their ratings.
Create the file src/pages/Home.js and the following basic component:
For now, it’s just a component that shows a
Since we’re going to fetch the restaurants from our MongoDB Realm App later on, we’ll be using a state for restaurants:
Then, we’ll loop over the restaurants and display them:
Let’s create src/components/RestaurantCard.js with the following content:
We’re first calculating the average grade for the restaurant, then we’re just displaying a card with the restaurant’s name and the average grade.
So, our home page should show a list of cards with restaurant names and grades. What’s left is to actually link it to the data in our Realm app.
Let’s go over how to connect to Realm Apps first. You first need an App ID. You’ll find the App ID on the Dashboard or you can click the copy icon in the sidebar.
Then, initialize the Realm App:
Notice we’re using the environment variable we set earlier.
Then inside the Home component, we’ll use useEffect to fetch the data on first render:
Inside, we’ll log in the user anonymously and then fetch the restaurants data. Since earlier we allowed all users to read all data, even users who aren’t logged in can read the data.
To login a user anonymously:
After that, we’ll get the MongoDB client for our collection using the user we just logged in:
As you can tell, by using app.currentUser we’re referring to the currently logged-in user. Then, we get the MongoDB client for that user. This means that the access to the data is restricted based on the user that is logged in, just like we defined above.
Next step would be to get the restaurants from restaurants collection and set the restaurants state:
And with this, our code will display the restaurants once we retrieve them from MongoDB Realm App. We’ll add also some loading to make sure we can see the loading:
We’ll also create src/components/Loading.js :
And that’s it! The home page now is ready. Only thing left is to use react-router in src/App.js to ensure multiple pages:
Let’s now run the server:
After some loading, you’ll see the restaurants with their average grades:
Next, we’ll create authentication forms to allow users to create accounts and login.
Authentication Page
Since the user just needs to enter the email and password to Sign up and Log in, we’ll just create one Authentication component that changes behavior based on type prop that determines whether the form is being used to create an account or login.
Before we start, let’s install Formik and Yup to make creating a form easier:
Then, create src/pages/Authentication.js with the following content:
We’re using Formik to create a form that has two fields, email, and password. We’re also using yup it to create a validation schema. On form submit if everything is valid, the function submitHandler will run which accepted the values object.
Create src/MongoContext.js with the following content:
This will wrap a component with MongoContext.Consumer then pass it the mongoContext prop, which will hold all the objects we’re storing in the context and their setters.
Now, we have a context that holds all the objects and their setters, then we’re passing it to a route’s component.
If you try running the server and going to the website, you’ll see that everything is working perfectly as before.
Back to the Authentication component, we’ll now pass it the mongoContext prop:
Last thing we need to add is to redirect the user if they’re already logged in. To do that, first create src/utils.js which will hold the function isAnon to determine whether the user is logged in:
Where providerType will be anon-user if the user is not logged in.
Then, whenever the user in the context changes, we’ll check if the user is logged in and then we’ll redirect to home if true.
Our Authentication component is now done! Let’s add signin and signup routes in src/App.js :
We’ll also need a LogOut page so create src/pages/Logout.js with the following content:
We’re first checking if the user is already not logged in and we’re redirecting them to homepage if that’s the case. Then, we’re displaying the loading component and inside useEffect we’re logging the user out using:
After that, we’re setting the user as anonymous user again and reinitializing the MongoDB Client:
And with that, we have our log out page. We just need to add it to the routes in src/App.js :
Lastly, we’ll create a src/components/Navigation.js component to show a navigation bar with our links:
We’re passing it the user prop, then we’re checking if the user is logged in, we’ll show the log out link. If not, we’ll show the sign in and sign up links.
Add the Navigation component in src/App.js :
We’re done! Run the server if you aren’t already:
You’ll see we have a navigation bar that shows the sign in and sign up links when we’re not logged in. Try to sign up, log out, sign it, do different things. To check if the users are actually being created, on the Realm platform, click on «App Users» in the sidebar. You’ll see a list of users with the type of user either Anonymous or Email/Password.
Conclusion
In the next part, we’ll add a form for users to create their own reviews. We’ll be able to test the permissions we added earlier and see how the users are restricted based on the roles we create.
You can read part 2 here.
If you would like to connect and talk more about this article or programming in general, you can find me on my twitter account @shahednasserr
Subscribe to Newsletter
Subscribe to the newsletter to be notified of new tutorials and articles!
Thank you!
You have successfully joined our subscriber list.



















