diff --git a/examples/react-native/v12/TestApp/App.tsx b/examples/react-native/v12/TestApp/App.tsx
index 98d4afffc6..8e95630f7b 100644
--- a/examples/react-native/v12/TestApp/App.tsx
+++ b/examples/react-native/v12/TestApp/App.tsx
@@ -12,6 +12,7 @@ import {ObjectModels} from './src/components/object-models/ObjectModels';
import {RelationshipExamples} from './src/components/relationships/RealmWrapper';
import {CompensatingWriteErrorHandling} from './src/components/errors/CompensatingWriteWrapper';
import {EncryptMetadata} from './src/components/encryption/EncryptMetadata';
+import { AppWithAuthHook } from './src/components/app-services/use-app';
// Screens
import {HomeScreen} from './src/screens/HomeScreen';
@@ -79,6 +80,10 @@ function App(): JSX.Element {
name="Authentication"
component={AuthenticationScreen}
/>
+
{props => (
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/examples/react-native/v12/TestApp/src/components/app-services/use-app.test.tsx b/examples/react-native/v12/TestApp/src/components/app-services/use-app.test.tsx
new file mode 100644
index 0000000000..3520b39f8d
--- /dev/null
+++ b/examples/react-native/v12/TestApp/src/components/app-services/use-app.test.tsx
@@ -0,0 +1,24 @@
+import 'react-native';
+import React from 'react';
+import {AppWithAuthHook} from './use-app';
+import {render, screen, userEvent} from '@testing-library/react-native';
+import '@testing-library/jest-dom';
+
+test('App with auth hook', async () => {
+ render();
+
+ const user = userEvent.setup();
+
+ const logInButton = screen.queryByTestId('log-in');
+
+ if (logInButton) {
+ await user.press(logInButton);
+ }
+
+ const loggedInUserText = await screen.findByTestId('logged-in-user-id');
+ expect(loggedInUserText).not.toEqual(null);
+
+ const notYetLoggedIn = screen.queryByText('No one is logged in yet.');
+
+ expect(notYetLoggedIn).not.toBeInTheDocument();
+});
diff --git a/examples/react-native/v12/TestApp/src/components/app-services/use-app.tsx b/examples/react-native/v12/TestApp/src/components/app-services/use-app.tsx
new file mode 100644
index 0000000000..297cf06f30
--- /dev/null
+++ b/examples/react-native/v12/TestApp/src/components/app-services/use-app.tsx
@@ -0,0 +1,93 @@
+// :snippet-start: app-config-imports
+import React from 'react';
+import {AppProvider, UserProvider} from '@realm/react';
+// :snippet-end:
+// :snippet-start: import-use-app
+// :uncomment-start:
+//import React from 'react';
+// :uncomment-end:
+import {useApp} from '@realm/react';
+// :snippet-end:
+import {useAuth} from '@realm/react';
+import {Text, View, Pressable, StyleSheet} from 'react-native';
+import {APP_ID} from '../../../appServicesConfig';
+
+// :snippet-start: app-config
+export const AppWithAuthHook = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+// :snippet-end:
+
+const LogIn = () => {
+ const {logInWithAnonymous} = useAuth();
+
+ return (
+
+ No one is logged in yet.
+
+ Log in
+
+
+ );
+};
+
+// :snippet-start: use-app
+function MyApp() {
+ const app = useApp();
+ // Proceed to app logic...
+ // :remove-start:
+ return (
+ "Logged in as user with ID: {app.currentUser?.id}"
+ );
+ // :remove-end:
+}
+// :snippet-end:
+
+const styles = StyleSheet.create({
+ section: {
+ flex: 1,
+ marginTop: 8,
+ paddingVertical: 12,
+ alignItems: 'center',
+ },
+ textInput: {
+ backgroundColor: '#C5CAE9',
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ marginVertical: 5,
+ },
+ inputGroup: {
+ width: '100%',
+ },
+ buttonGroup: {
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ marginVertical: 12,
+ paddingVertical: 8,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ button: {
+ backgroundColor: '#3F51B5',
+ borderWidth: StyleSheet.hairlineWidth,
+ borderColor: '#ffffff',
+ paddingVertical: 5,
+ paddingHorizontal: 8,
+ marginVertical: 5,
+ marginHorizontal: 8,
+ },
+ buttonText: {
+ color: '#ffffff',
+ textAlign: 'center',
+ },
+});
diff --git a/examples/react-native/v12/TestApp/src/navigation/types.tsx b/examples/react-native/v12/TestApp/src/navigation/types.tsx
index 53b636a032..e7c1d63c97 100644
--- a/examples/react-native/v12/TestApp/src/navigation/types.tsx
+++ b/examples/react-native/v12/TestApp/src/navigation/types.tsx
@@ -16,6 +16,7 @@ export type RootStackParamList = {
encryptionKey: ArrayBuffer;
};
Quickstart: undefined;
+ AppWithAuthHook: undefined;
};
export type SubscriptionStackParamList = {
diff --git a/examples/react-native/v12/TestApp/testSetup.ts b/examples/react-native/v12/TestApp/testSetup.ts
index 8ce7fa9409..f879698ee5 100644
--- a/examples/react-native/v12/TestApp/testSetup.ts
+++ b/examples/react-native/v12/TestApp/testSetup.ts
@@ -10,6 +10,7 @@ jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
// Suppress noisy warnings. Should probably investigate
// all warnings at some point.
global.console.warn = jest.fn();
+global.console.error = jest.fn();
beforeEach(async () => {
// Close and remove all realms in the default directory.
diff --git a/source/examples/generated/react-native/ts/use-app.test.snippet.use-app.tsx b/source/examples/generated/react-native/ts/use-app.test.snippet.use-app.tsx
deleted file mode 100644
index f4aba819b1..0000000000
--- a/source/examples/generated/react-native/ts/use-app.test.snippet.use-app.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import {useApp} from '@realm/react';
-import {Credentials} from 'realm';
-function MyApp() {
- const app = useApp();
- function logInAnonymousUser() {
- app.logIn(Credentials.anonymous());
- }
- // ...
-}
diff --git a/source/examples/generated/react-native/v12/use-app.snippet.app-config-imports.tsx.rst b/source/examples/generated/react-native/v12/use-app.snippet.app-config-imports.tsx.rst
new file mode 100644
index 0000000000..b57b32ee1f
--- /dev/null
+++ b/source/examples/generated/react-native/v12/use-app.snippet.app-config-imports.tsx.rst
@@ -0,0 +1,4 @@
+.. code-block:: typescript
+
+ import React from 'react';
+ import {AppProvider, UserProvider} from '@realm/react';
diff --git a/source/examples/generated/react-native/v12/use-app.snippet.app-config.tsx.rst b/source/examples/generated/react-native/v12/use-app.snippet.app-config.tsx.rst
new file mode 100644
index 0000000000..b948b7b227
--- /dev/null
+++ b/source/examples/generated/react-native/v12/use-app.snippet.app-config.tsx.rst
@@ -0,0 +1,13 @@
+.. code-block:: typescript
+
+ export const AppWithAuthHook = () => {
+ return (
+
+
+
+
+
+
+
+ );
+ };
diff --git a/source/examples/generated/react-native/v12/use-app.snippet.import-use-app.tsx.rst b/source/examples/generated/react-native/v12/use-app.snippet.import-use-app.tsx.rst
new file mode 100644
index 0000000000..7884015276
--- /dev/null
+++ b/source/examples/generated/react-native/v12/use-app.snippet.import-use-app.tsx.rst
@@ -0,0 +1,4 @@
+.. code-block:: typescript
+
+ import React from 'react';
+ import {useApp} from '@realm/react';
diff --git a/source/examples/generated/react-native/v12/use-app.snippet.use-app.tsx.rst b/source/examples/generated/react-native/v12/use-app.snippet.use-app.tsx.rst
new file mode 100644
index 0000000000..823c73a19e
--- /dev/null
+++ b/source/examples/generated/react-native/v12/use-app.snippet.use-app.tsx.rst
@@ -0,0 +1,6 @@
+.. code-block:: typescript
+
+ function MyApp() {
+ const app = useApp();
+ // Proceed to app logic...
+ }
diff --git a/source/sdk/react-native/api-reference/app-provider.txt b/source/sdk/react-native/api-reference/app-provider.txt
index 46c7f16277..3eb2760667 100644
--- a/source/sdk/react-native/api-reference/app-provider.txt
+++ b/source/sdk/react-native/api-reference/app-provider.txt
@@ -4,6 +4,10 @@
AppProvider (@realm/react)
==========================
+.. meta::
+ :description: Learn how to use the AppProvider ReactElement hooks to work with an App Services App.
+ :keywords: code example
+
.. facet::
:name: genre
:values: reference
@@ -646,8 +650,8 @@ useApp()
The ``useApp()`` hook provides access to a :js-sdk:`Realm.App `
instance.
-.. literalinclude:: /examples/generated/react-native/ts/use-app.test.snippet.use-app.tsx
- :language: typescript
+.. include:: /examples/generated/react-native/v12/use-app.snippet.import-use-app.tsx.rst
+.. include:: /examples/generated/react-native/v12/use-app.snippet.use-app.tsx.rst
*Returns*
diff --git a/source/sdk/react-native/app-services/connect-to-app-services-app.txt b/source/sdk/react-native/app-services/connect-to-app-services-app.txt
index c376a72fa0..8c3283764b 100644
--- a/source/sdk/react-native/app-services/connect-to-app-services-app.txt
+++ b/source/sdk/react-native/app-services/connect-to-app-services-app.txt
@@ -4,13 +4,13 @@
Connect to an Atlas App Services App - React Native SDK
=======================================================
-.. meta::
- :description: Connect your Atlas Device SDK for React Native client app to the Atlas App Services backend.
- :keywords: code example
+.. meta::
+ :description: Connect to Atlas App Services from the Atlas Device SDK. Specify configuration details to customize App access.
+ :keywords: code example
.. facet::
:name: genre
- :values: tutorial
+ :values: reference
.. contents:: On this page
:local:
@@ -38,9 +38,11 @@ Configure the App Client
To set up your App client, pass the App ID string
to the ``id`` prop of the ``AppProvider``.
Wrap any components that need to access the App with the ``AppProvider``.
+In this example, we wrap the :ref:`UserProvider `
+in the ``AppProvider`` to authenticate a user.
-.. literalinclude:: /examples/generated/react-native/ts/app-provider.test.snippet.app-provider.tsx
- :language: typescript
+.. include:: /examples/generated/react-native/v12/use-app.snippet.app-config-imports.tsx.rst
+.. include:: /examples/generated/react-native/v12/use-app.snippet.app-config.tsx.rst
You can create multiple App client instances to connect to multiple
Apps. All App client instances that share the same App ID use the same
@@ -68,11 +70,10 @@ Retrieve an Instance of the App Client
--------------------------------------
All components wrapped within an ``AppProvider`` can access the :js-sdk:`App `
-client with the ``useApp()`` hook. Using the App, you can authenticate users
-and access App Services.
+client with the ``useApp()`` hook.
-.. literalinclude:: /examples/generated/react-native/ts/use-app.test.snippet.use-app.tsx
- :language: typescript
+.. include:: /examples/generated/react-native/v12/use-app.snippet.import-use-app.tsx.rst
+.. include:: /examples/generated/react-native/v12/use-app.snippet.use-app.tsx.rst
.. _react-native-retrieve-client-outside-provider: