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: