Providers & Hooks
On this page
The @realm/react
library offers custom React components that eliminate the boilerplate needed to
develop a React app using JavaScript-based Atlas Device SDKs. The components leverage the
Provider design pattern to manage your Atlas connection, user creation and authentication, and
data management.
AppProvider
: Used to connect to your Atlas App Services App Client, including for user authentication.UserProvider
: Used to access the logged-in user object.RealmProvider
: Used to work with the configured database.
Use these providers to develop with frameworks and for platforms that support a React environment, including: React Native, Web, and Electron.
Getting Started with Providers
Like all React components, you call providers using HTML opening and closing tags. Nesting a component within another component's tags creates a parent-child relationship between them, where child components can access the context created by their parent component.
Context refers to the information made accessible by a provider. For example, the
RealmProvider
context is the Realm database it connects to, so all components nested in the
RealmProvider
have access to that database.
Props
Components take parameters called props as input, passed into the opening tag. The props passed into a parent component help create the context inherited by the components it wraps. Each Provider has different props you can use for configuration.
Configure your Providers
Your app's needs determine what providers you use, as all three providers are not always necessary. The example below walks through configuring all three providers. If your app does not need a certain provider, you can skip the steps and omit the code for that provider.
To configure your providers:
Import
RealmProvider
,AppProvider
, andUserProvider
from@realm/react
.Configure
AppProvider
.Pass your App Services App ID string to the
id
prop of theAppProvider
.Add other configuration object properties as props to
AppProvider
as needed.
Configure
UserProvider
and nest it withinAppProvider
.Pass a component that logs in a user to the
fallback
prop. The app renders this component if there is no authenticated user.
Configure
RealmProvider
and nest it withinUserProvider
.Pass your object models to the
schema
prop.If configuring a synced database, use the
sync
prop. Sync properties are defined by a Sync Config Object.To sync data, you must set up a sync subscription. The example below uses an initial subscription, but you can also set up subscriptions in
RealmProvider
child components.Add other configuration object properties as props to
RealmProvider
as needed.
Nest your app components in the providers.
Once your providers have been configured and nested as described above, nest your app components within the provider whose context it needs to access. Generally, you can nest your components within the
RealmProvider
to ensure they have access to all three providers' contexts.
The rendering of each component is dependent on the successful
execution of its parent components' functionality. For example, while AppProvider
is
connecting to your app's App Services backend, or if AppProvider
is unable to connect, the
components it wraps will not render. In these cases, the provider's fallback component is
rendered instead.
You must nest the providers as shown below to ensure each has access to its required context:
import React from 'react'; import {AppProvider, UserProvider, RealmProvider} from '@realm/react'; function AppWrapperSync() { return ( <AppProvider id={APP_ID}> <UserProvider fallback={LogIn}> <RealmProvider schema={[YourObjectModel]} sync={{ flexible: true, initialSubscriptions: { update(subs, realm) { subs.add(realm.objects(YourObjectModel)); }, }, }}> <RestOfApp /> </RealmProvider> </UserProvider> </AppProvider> ); }
Note
Exposing more than one database using createRealmContext()
The example above details how to configure and expose a single database using a RealmProvider
imported directly from @realm/react
.
For information about using createRealmContext()
to configure a database or exposing more
than one database, see Create Context with createRealmContext() below.
Working with Providers using Hooks
To use the provider's context in your app's components, you can use Hooks.
Hooks act as functions used to access states in your app. React offers built-in Hooks you can use either on their own or to build custom Hooks.
There are two important rules to consider when working with Hooks:
Hooks can only be used at the top level of a React component.
Hooks can only be called in a React component or a custom Hook, not in regular JavaScript functions.
The @realm/react
library has custom Hooks for each provider you can
use to access a provider's context in the components it wraps.
RealmProvider Hooks
useRealm()
useRealm(): Realm
The useRealm()
Hook returns an opened database instance. The database instance
gives you access to database methods and properties. For example, you can call
realm.write()
to add a Realm Object to your database.
To learn more about modifying data in your database, refer to Write Transactions.
const CreatePersonInput = () => { const [name, setName] = useState(''); const realm = useRealm(); const handleAddPerson = () => { realm.write(() => { realm.create('Person', {_id: PERSON_ID, name: name, age: 25}); }); }; return ( <> <TextInput value={name} onChangeText={setName} /> <Button onPress={() => handleAddPerson()} title='Add Person' /> </> ); };
Returns
Realm
Returns a database instance from theRealmProvider
context.
useObject()
useObject<T>(type, sdks-open-synced-database-offlineKey): T & Realm.Object<T> | null
The useObject()
Hook returns a Realm Object for a given
primary key. You can pass an object class
or the class name as a string and the primary key.
The useObject()
Hook returns null
if the object doesn't exist or you have
deleted it. The Hook will automatically subscribe to updates and rerender the
component using the Hook on any change to the object.
const TaskItem = ({_id}: {_id: number}) => { const myTask = useObject(Task, _id); return ( <View> {myTask ? ( <Text> {myTask.name} is a task with the priority of: {myTask.priority} </Text> ) : null} </View> ); };
Parameters
type: string
A string that matches your object model's class name or a reference to a class that extends Realm.Object.primaryKey: T[keyof T]
The primary key of the desired object.
Returns
Realm.Object | null
A Realm Object ornull
if no object is found.
useQuery()
useQuery<T>(type, query?, deps?): Realm.Results<T & Realm.Object<T>>
The useQuery()
Hook returns a result that is a
collection of Realm Objects of a given type. These are the results of your query. A query can
be an object class or the class name as a string.
The useQuery()
method subscribes to updates to any objects in the collection
and rerenders the component using it on any change to the results.
You can use .filtered()
and .sorted()
to filter and sort your query
results. Do this in the query
argument of useQuery
so that
they only run when there are changes in the dependency array. For more examples,
refer to the Read Objects page.
const TaskList = () => { const [priority, setPriority] = useState(4); // filter for tasks with a high priority const highPriorityTasks = useQuery( Task, tasks => { return tasks.filtered('priority >= $0', priority); }, [priority], ); // filter for tasks that have just-started or short-running progress const lowProgressTasks = useQuery(Task, tasks => { return tasks.filtered( '$0 <= progressMinutes && progressMinutes < $1', 1, 10, ); }); return ( <> <Text>Your high priority tasks:</Text> {highPriorityTasks.map(taskItem => { return <Text>{taskItem.name}</Text>; })} <Text>Your tasks without much progress:</Text> {lowProgressTasks.map(taskItem => { return <Text>{taskItem.name}</Text>; })} </> ); };
Parameters
type: string
A string that matches your object model's class name or a reference to a class that extends Realm.Object.query?: QueryCallback<T>
A query function that can filter and sort query results. Builds onuseCallback
to memoize the query function.deps?: DependencyList
A list of query function dependencies that's used to memoize the query function.
Returns
Realm.Results<T>
A Realm Object ornull
if no object is found.
UserProvider Hooks
useUser()
useUser<FunctionsFactoryType, CustomDataType, UserProfileDataType>(): Realm.User<FunctionsFactoryType, CustomDataType, UserProfileDataType>
The useUser()
Hook provides access to the logged-in user. For example,
you can use useUser()
to log the current user out.
When changes to the user object happen, this Hook will rerender its parent
component. For example, if you call user.refreshCustomData
to get updated
custom user data, the useUser()
parent component will rerender.
function UserInformation() { const user = useUser(); const {logOut} = useAuth(); const performLogout = () => { logOut(); }; // Add UI for logging out... }
Returns
Realm.User
An instance of the currently-authenticated Atlas user.
AppProvider Hooks
useApp()
useApp<FunctionsFactoryType, CustomDataType>(): Realm.App<FunctionsFactoryType, CustomDataType>
Example
The useApp()
Hook provides access to a Realm.App
instance.
import React from 'react'; import {useApp} from '@realm/react';
function MyApp() { const app = useApp(); // Proceed to app logic... }
Returns
Realm.App
An instance of the currentRealm.App
created byAppProvider
.
useAuth()
useAuth(): UseAuth
You destructure the useAuth()
Hook result into a result
and authentication method.
result
result: AuthResult
Result of authentication Hook operation. For example, result.operation
gives
you the name of the current operation.
Enum values
state
: Can be"not-started"
,"pending"
,"success"
,"error"
.operation
: For a list of all operation names, refer to the API documentation.pending
: Can betrue
orfalse
.success
: Can betrue
orfalse
.error
: Error-based object or undefined.
Authentication Methods
The authentication method specifies how you want users to login to your app. useAuth
has an authentication method for every App Services authentication provider.
Operation | Parameter | Example | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
logIn | credentials : An Atlas credential supplied by any supported Atlas App Services
authentication provider. | Logs in a user with any authentication mechanism supported by Atlas App Services. If called when a user is logged in, the current user switches to the new user. Usually, it's better to use the more specific login methods.
| ||||||||||||||||
logInWithAnonymous | None | Log in with the anonymous authentication provider.
| ||||||||||||||||
logInWithApiKey | key : A string that is linked to an App Services user. | Log in with an API key.
| ||||||||||||||||
logInWithEmailPassword | credentials : An object with email and password fields. | Log in with Email/Password.
| ||||||||||||||||
logInWithJWT | credentials : A string representation of a user's JWT. | Log in with a JSON Web Token (JWT).
| ||||||||||||||||
logInWithGoogle | credentials : An object with an idToken or authCode field that
should contain the string token you get from Google Identity Services. | Log in with Google.
| ||||||||||||||||
logInWithApple | idToken : A string you get from the Apple SDK. | Log in with Apple.
| ||||||||||||||||
logInWithFacebook | accessToken : A string you get from the Facebook SDK. | Log in with Facebook.
| ||||||||||||||||
logInWithFunction | payload : An object that contains user information you want to pass to
the App Services function that processes log in requests. | Log in with a custom function.
| ||||||||||||||||
logOut | None | Logs out the current user.
|
useEmailPasswordAuth()
You destructure the useEmailPasswordAuth()
Hook result into a result
and authentication operation.
result
result: AuthResult
Result of operation. For example, result.operation
gives you the name of the current
operation.
Enum values
state
: Can be"not-started"
,"pending"
,"success"
,"error"
.operation
: For a list of all operation names, refer to the API documentation.pending
: Can betrue
orfalse
.success
: Can betrue
orfalse
.error
: Error-based object or undefined.
Authentication Operations
useEmailPasswordAuth
has a number of operations to facilitate email and password user authentication.
Operation | Parameter | Example | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
logIn | credentials : An object that contains email and password properties. | Logs a user in using an email and password. You could also call
| |||||||||||||||||||||
logOut | None | Logs out the current user.
| |||||||||||||||||||||
register | args : An object that contains email and password properties. | Registers a new user. Requires a user email and password.
| |||||||||||||||||||||
confirm | args : An object that contains token and tokenId properties. | Confirms a user account. Requires a
| |||||||||||||||||||||
resendConfirmationEmail | args : An object that contains an email property. | Resends a confirmation email.
| |||||||||||||||||||||
retryCustomConfirmation | args : An object that contains an email property. | Retries confirmation with a custom function.
| |||||||||||||||||||||
sendResetPasswordEmail | args : An object that contains an email property. | Sends a password reset email.
| |||||||||||||||||||||
resetPassword | args : An object that contains token , tokenId , and password
properties. | Resets a user's password.
| |||||||||||||||||||||
callResetPasswordFunction |
| Calls your App Services backend password reset function. Can pass arguments to the function as needed.
|
Create Context with createRealmContext()
createRealmContext(realmConfig?): RealmContext
Use createRealmContext()
to configure more than one database. The createRealmContext()
method creates a React Context
object for a database with a given Configuration. The Context
object contains the following:
A Context Provider component that wraps around child components and provides them with access to Hooks.
Various prebuilt Hooks that access the configured database.
To work with more than one database, you need to destructure a new provider and its
associated Hooks from the result of createRealmContext()
. You can call this new database
provider and use its associated Hooks the same way you would with the RealmProvider
imported from the @realm/react
library. Namespace your providers to avoid confusion about
which provider and Hooks you're working with.
Parameters
realmConfig?: Realm.Configuration
All properties of BaseConfiguration can be used.
Returns
RealmContext
An object containing aRealmProvider
component, and theuseRealm
,useQuery
anduseObject
Hooks.
For a detailed guide, refer to Expose More Than One Database.