From 5c0c73c56331e09bf422c064ff7dc2ae07f5fbf0 Mon Sep 17 00:00:00 2001 From: Kyle Rollins <115574589+krollins-mdb@users.noreply.github.com> Date: Tue, 31 Jan 2023 15:44:34 -0600 Subject: [PATCH] (DOCSP-26995) Reframe RN SDK open and close realm page (#2529) ## Pull Request Info The Open and Close a Realm page needed a nearly complete overhaul because these concepts are very different with `@realm/react`. I plan to re-evaluate the "Key Concept" section after we've finished the current Realm React epic. ### Jira - https://jira.mongodb.org/browse/DOCSP-26995 ### Staged Changes - [Configure a Realm](https://docs-mongodbcom-staging.corp.mongodb.com/realm/docsworker-xlarge/DOCSP-26995/sdk/react-native/realm-database/configure-a-realm/) ### Reminder Checklist If your PR modifies the docs, you might need to also update some corresponding pages. Check if completed or N/A. - [x] Create Jira ticket for corresponding docs-app-services update(s), if any - [x] Checked/updated Admin API - [x] Checked/updated CLI reference ### Review Guidelines [REVIEWING.md](https://github.com/mongodb/docs-realm/blob/master/REVIEWING.md) ### Animal wearing a hat ![](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTC2T1wlVitCxsZHwKb18NazHbiFmtF0_FeNw&usqp=CAU) --------- Co-authored-by: Ben Perlmutter <90647379+mongodben@users.noreply.github.com> --- config/redirects | 4 + examples/react-native/README.md | 3 + .../react-native/__tests__/ts/RealmConfig.js | 27 +++++ .../configure-realm-local.test.tsx | 39 ++++++ .../configure-realm-multiple.test.tsx | 67 +++++++++++ .../configure-realm-sync.test.tsx | 44 +++++++ ...ealmConfig.snippet.create-realm-context.js | 9 ++ .../js/RealmConfig.snippet.in-memory-realm.js | 4 + ...alm-local.test.snippet.configure-realm.tsx | 12 ++ ...ltiple.test.snippet.two-realm-contexts.tsx | 26 ++++ ...sync.test.snippet.configure-realm-sync.tsx | 17 +++ source/sdk/react-native.txt | 2 +- source/sdk/react-native/realm-database.txt | 2 +- .../react-native/realm-database/bundle.txt | 2 +- .../realm-database/configure-a-realm.txt | 112 ++++++++++++++++++ .../react-native/realm-database/encrypt.txt | 3 +- .../realm-database/open-and-close-a-realm.txt | 82 ------------- .../react-native/realm-database/overview.txt | 3 +- 18 files changed, 369 insertions(+), 89 deletions(-) create mode 100644 examples/react-native/__tests__/ts/RealmConfig.js create mode 100644 examples/react-native/__tests__/ts/realm-database/configure-realm-local.test.tsx create mode 100644 examples/react-native/__tests__/ts/realm-database/configure-realm-multiple.test.tsx create mode 100644 examples/react-native/__tests__/ts/realm-database/configure-realm-sync.test.tsx create mode 100644 source/examples/generated/react-native/js/RealmConfig.snippet.create-realm-context.js create mode 100644 source/examples/generated/react-native/js/RealmConfig.snippet.in-memory-realm.js create mode 100644 source/examples/generated/react-native/ts/configure-realm-local.test.snippet.configure-realm.tsx create mode 100644 source/examples/generated/react-native/ts/configure-realm-multiple.test.snippet.two-realm-contexts.tsx create mode 100644 source/examples/generated/react-native/ts/configure-realm-sync.test.snippet.configure-realm-sync.tsx create mode 100644 source/sdk/react-native/realm-database/configure-a-realm.txt delete mode 100644 source/sdk/react-native/realm-database/open-and-close-a-realm.txt diff --git a/config/redirects b/config/redirects index ef579ccd26..b52d86e538 100644 --- a/config/redirects +++ b/config/redirects @@ -1004,3 +1004,7 @@ raw: ${prefix}/sdk/dotnet/examples/work-with-users -> ${base}/sdk/dotnet/work-wi raw: ${prefix}/sdk/dotnet/advanced-guides -> ${base}/sdk/dotnet/ raw: ${prefix}/sdk/dotnet/advanced-guides/debugging -> ${base}/sdk/dotnet/ raw: ${prefix}/sdk/dotnet/advanced-guides/testing -> ${base}/sdk/dotnet/ + +# Realm React Guidance (https://jira.mongodb.org/browse/DOCSP-23395) + +raw: ${prefix}/sdk/react-native/realm-database/open-and-close-a-realm -> ${base}/sdk/react-native/realm-database/configure-a-realm diff --git a/examples/react-native/README.md b/examples/react-native/README.md index d0d240d254..1076014824 100644 --- a/examples/react-native/README.md +++ b/examples/react-native/README.md @@ -18,6 +18,9 @@ This project uses [npm](https://www.npmjs.com/) to manage dependencies. To get s npm install ``` +> **Warning** +> Currently, `npm install` fails in Node.js v16.17.0. We recommend using Node.js v16.14.0. + ### Run Tests This project defines a unit test suite that tests both JS and TS code examples. You can run them via: diff --git a/examples/react-native/__tests__/ts/RealmConfig.js b/examples/react-native/__tests__/ts/RealmConfig.js new file mode 100644 index 0000000000..d556f19e84 --- /dev/null +++ b/examples/react-native/__tests__/ts/RealmConfig.js @@ -0,0 +1,27 @@ +// :snippet-start: create-realm-context +import {createRealmContext} from '@realm/react'; +// Import all of your models. +import Invoice from './Models/Invoice'; +import Business from './Models/Business'; +// :remove-start: +import Address from './Models/Address'; +import Contact from './Models/Contact'; +// :remove-end: + +export const RealmContext = createRealmContext({ + // Pass all of your models into the schema value. + schema: [Invoice, Business], +}); +// :snippet-end: + +export const SecondRealmContext = createRealmContext({ + // Pass all of your secondary models into the schema value. + schema: [Address, Contact], +}); + +// :snippet-start: in-memory-realm +export const InMemoryRealmContext = createRealmContext({ + schema: [Address, Contact], + inMemory: true, +}); +// :snippet-end: diff --git a/examples/react-native/__tests__/ts/realm-database/configure-realm-local.test.tsx b/examples/react-native/__tests__/ts/realm-database/configure-realm-local.test.tsx new file mode 100644 index 0000000000..a0312c4d58 --- /dev/null +++ b/examples/react-native/__tests__/ts/realm-database/configure-realm-local.test.tsx @@ -0,0 +1,39 @@ +// :snippet-start: configure-realm +import React from 'react'; +import {RealmContext} from '../RealmConfig'; +// :remove-start: +import {render} from '@testing-library/react-native'; +import {useApp} from '@realm/react'; +import {View, Text} from 'react-native'; + +const APP_ID = 'example-testers-kvjdy'; + +function MyApp() { + const app = useApp(); + + if (app.id !== APP_ID) { + throw new Error('Did not instantiate app client'); + } + + return ( + + Foo + + ); +} +// :remove-end: + +function AppWrapperLocal() { + const {RealmProvider} = RealmContext; + + return ( + + + + ); +} +// :snippet-end: + +test('Instantiate RealmProvider correctly', () => { + render(); +}); diff --git a/examples/react-native/__tests__/ts/realm-database/configure-realm-multiple.test.tsx b/examples/react-native/__tests__/ts/realm-database/configure-realm-multiple.test.tsx new file mode 100644 index 0000000000..a8a08cf85c --- /dev/null +++ b/examples/react-native/__tests__/ts/realm-database/configure-realm-multiple.test.tsx @@ -0,0 +1,67 @@ +// :snippet-start: two-realm-contexts +import React from 'react'; +import {AppProvider, UserProvider} from '@realm/react'; +import {RealmContext} from '../RealmConfig'; +import {SecondRealmContext} from '../RealmConfig'; +// :remove-start: +import {render} from '@testing-library/react-native'; +import {useApp} from '@realm/react'; +import {View, Text} from 'react-native'; + +const APP_ID = 'example-testers-kvjdy'; + +function AppSectionOne() { + const app = useApp(); + + if (app.id !== APP_ID) { + throw new Error('Did not instantiate app client'); + } + + return ( + + Foo + + ); +} + +function AppSectionTwo() { + const app = useApp(); + + if (app.id !== APP_ID) { + throw new Error('Did not instantiate app client'); + } + + return ( + + Bar + + ); +} +// :remove-end: + +function TwoRealmsWrapper() { + const {RealmProvider: RealmProvider} = RealmContext; + const {RealmProvider: SecondRealmProvider} = SecondRealmContext; + + return ( + + + {/* This realm uses Flexible Sync. */} + console.error(error)}} + > + + + {/* This is a separate local-only realm. */} + + + + + + ); +} +// :snippet-end: + +test('Instantiate SecondRealmProvider correctly', () => { + render(); +}); diff --git a/examples/react-native/__tests__/ts/realm-database/configure-realm-sync.test.tsx b/examples/react-native/__tests__/ts/realm-database/configure-realm-sync.test.tsx new file mode 100644 index 0000000000..a01c2b21a9 --- /dev/null +++ b/examples/react-native/__tests__/ts/realm-database/configure-realm-sync.test.tsx @@ -0,0 +1,44 @@ +// :snippet-start: configure-realm-sync +import React from 'react'; +import {AppProvider, UserProvider} from '@realm/react'; +import {RealmContext} from '../RealmConfig'; +// :remove-start: +import {render} from '@testing-library/react-native'; +import {useApp} from '@realm/react'; +import {View, Text} from 'react-native'; + +const APP_ID = 'example-testers-kvjdy'; + +function MyApp() { + const app = useApp(); + + if (app.id !== APP_ID) { + throw new Error('Did not instantiate app client'); + } + + return ( + + Foo + + ); +} +// :remove-end: + +function AppWrapperSync() { + const {RealmProvider} = RealmContext; + + return ( + + + console.error(error)}}> + + + + + ); +} +// :snippet-end: + +test('Instantiate RealmProvider correctly', () => { + render(); +}); diff --git a/source/examples/generated/react-native/js/RealmConfig.snippet.create-realm-context.js b/source/examples/generated/react-native/js/RealmConfig.snippet.create-realm-context.js new file mode 100644 index 0000000000..6d089bddf5 --- /dev/null +++ b/source/examples/generated/react-native/js/RealmConfig.snippet.create-realm-context.js @@ -0,0 +1,9 @@ +import {createRealmContext} from '@realm/react'; +// Import all of your models. +import Invoice from './Models/Invoice'; +import Business from './Models/Business'; + +export const RealmContext = createRealmContext({ + // Pass all of your models into the schema value. + schema: [Invoice, Business], +}); diff --git a/source/examples/generated/react-native/js/RealmConfig.snippet.in-memory-realm.js b/source/examples/generated/react-native/js/RealmConfig.snippet.in-memory-realm.js new file mode 100644 index 0000000000..e2a3d3014b --- /dev/null +++ b/source/examples/generated/react-native/js/RealmConfig.snippet.in-memory-realm.js @@ -0,0 +1,4 @@ +export const InMemoryRealmContext = createRealmContext({ + schema: [Address, Contact], + inMemory: true, +}); diff --git a/source/examples/generated/react-native/ts/configure-realm-local.test.snippet.configure-realm.tsx b/source/examples/generated/react-native/ts/configure-realm-local.test.snippet.configure-realm.tsx new file mode 100644 index 0000000000..6e7233b078 --- /dev/null +++ b/source/examples/generated/react-native/ts/configure-realm-local.test.snippet.configure-realm.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import {RealmContext} from '../RealmConfig'; + +function AppWrapperLocal() { + const {RealmProvider} = RealmContext; + + return ( + + + + ); +} diff --git a/source/examples/generated/react-native/ts/configure-realm-multiple.test.snippet.two-realm-contexts.tsx b/source/examples/generated/react-native/ts/configure-realm-multiple.test.snippet.two-realm-contexts.tsx new file mode 100644 index 0000000000..10daa62424 --- /dev/null +++ b/source/examples/generated/react-native/ts/configure-realm-multiple.test.snippet.two-realm-contexts.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import {AppProvider, UserProvider} from '@realm/react'; +import {RealmContext} from '../../RealmConfig'; +import {SecondRealmContext} from '../../RealmConfig'; + +function TwoRealmsWrapper() { + const {RealmProvider: RealmProvider} = RealmContext; + const {RealmProvider: SecondRealmProvider} = SecondRealmContext; + + return ( + + + {/* This realm uses Flexible Sync. */} + console.error(error)}} + > + + + {/* This is a separate local-only realm. */} + + + + + + ); +} diff --git a/source/examples/generated/react-native/ts/configure-realm-sync.test.snippet.configure-realm-sync.tsx b/source/examples/generated/react-native/ts/configure-realm-sync.test.snippet.configure-realm-sync.tsx new file mode 100644 index 0000000000..5f20257802 --- /dev/null +++ b/source/examples/generated/react-native/ts/configure-realm-sync.test.snippet.configure-realm-sync.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import {AppProvider, UserProvider} from '@realm/react'; +import {RealmContext} from '../RealmConfig'; + +function AppWrapperSync() { + const {RealmProvider} = RealmContext; + + return ( + + + console.error(error)}}> + + + + + ); +} diff --git a/source/sdk/react-native.txt b/source/sdk/react-native.txt index d4fe6dacc8..3b36099a7e 100644 --- a/source/sdk/react-native.txt +++ b/source/sdk/react-native.txt @@ -102,7 +102,7 @@ clients. You can configure your realm to do things like populate initial data on load, be encrypted, and more. To begin working with your data, - :ref:`configure and open a realm `. + :ref:`configure and open a realm `. .. step:: Read and Write Data diff --git a/source/sdk/react-native/realm-database.txt b/source/sdk/react-native/realm-database.txt index 33658a64f3..632fc4b772 100644 --- a/source/sdk/react-native/realm-database.txt +++ b/source/sdk/react-native/realm-database.txt @@ -17,7 +17,7 @@ Realm Database - React Native SDK Define a Realm Object Model Change an Object Model Schemas - Open & Close a Realm + Configure a Realm Write Transactions CRUD React to Changes diff --git a/source/sdk/react-native/realm-database/bundle.txt b/source/sdk/react-native/realm-database/bundle.txt index 92288dd2fa..c1d6729452 100644 --- a/source/sdk/react-native/realm-database/bundle.txt +++ b/source/sdk/react-native/realm-database/bundle.txt @@ -113,7 +113,7 @@ On a high level you: The realm is now bundled and will be included when a user downloads the app. To add the bundled realm file to your app's document directory, call :js-sdk:`Realm.copyBundledRealmFiles() ` - before you :ref:`open the realm `. + before you open the realm. ``Realm.copyBundledRealmFiles()`` adds all ``*.realm`` files from the application bundle to the application documents directory. This method doesn't override diff --git a/source/sdk/react-native/realm-database/configure-a-realm.txt b/source/sdk/react-native/realm-database/configure-a-realm.txt new file mode 100644 index 0000000000..12d8c9f797 --- /dev/null +++ b/source/sdk/react-native/realm-database/configure-a-realm.txt @@ -0,0 +1,112 @@ +.. _react-native-configure-realm: + +==================================== +Configure a Realm - React Native SDK +==================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +The ``@realm/react`` library exposes realms in your application using +`React Context objects `__ and Provider +components. You can access realms with React hooks. + +To configure and open a local realm, create a Context with the realm's configuration. The +Context exports a ``RealmProvider`` component that exposes a configured realm. +All child components of ``RealmProvider`` can access the realm using hooks. + +To learn how to open a realm using Device Sync, refer to +:ref:`Open a Synced Realm `. + +Create Realm Configuration +-------------------------- + +By passing a :js-sdk:`Configuration ` object to +``createRealmContext()``, you create a Context object that contains an open +realm and some hooks that give you access to the realm. + +The following example creates and exports a Context object so that it can be +used elsewhere. + +.. literalinclude:: /examples/generated/react-native/js/RealmConfig.snippet.create-realm-context.js + :language: javascript + :caption: RealmConfig.js + +Configure a Synced Realm +~~~~~~~~~~~~~~~~~~~~~~~~ + +To open a realm that synchronizes data with Atlas using Device Sync, +refer to :ref:`Open a Synced Realm `. + +Configure an In-Memory Realm +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To create a realm that runs entirely in memory without being written to a file, +add ``inMemory: true`` to your :js-sdk:`Realm.Configuration +` object: + +.. literalinclude:: /examples/generated/react-native/js/RealmConfig.snippet.in-memory-realm.js + :language: javascript + :emphasize-lines: 3 + +In-memory realms may use disk space if memory is running low, but files created +by an in-memory realm are deleted when you close the realm. + +Encrypt a Realm +~~~~~~~~~~~~~~~ + +To encrypt a realm database file on disk, refer to +:ref:`Encrypt a Realm `. + +Expose a Realm +-------------- + +```` is a wrapper that exposes a Context with Realm Database to +its child components. All child components inside ```` have access +to hooks that let you read, write, and update data. This is what a local-only +realm wrapper might look like: + +.. literalinclude:: /examples/generated/react-native/ts/configure-realm-local.test.snippet.configure-realm.tsx + :language: javascript + +Expose More Than One Realm +-------------------------- + +You can open more than one realm at a time by creating additional Contexts and +``RealmProvider`` components. + +.. literalinclude:: /examples/generated/react-native/ts/configure-realm-multiple.test.snippet.two-realm-contexts.tsx + :language: javascript + +Key Concept: Realm Files +------------------------ + +Realm Database stores a binary encoded version of every object and type in a +realm in a single ``.realm`` file. The file is located at a specific path that +you define when you open the realm. + +.. tip:: Implement Compacting in Your Production Application + + Every production application should implement a ``shouldCompactOnLaunch`` + callback to periodically reduce the realm file size. + +.. note:: Auxiliary Realm Files + + Realm Database creates additional files for each realm. + To learn more about these files, see :ref:`Realm Database Internals `. + +.. warning:: Use Caution When Deleting Realm Files + + In some circumstances, such as a client reset scenario, you might need to + delete a realm file and its auxiliary files. + + If you delete a realm file or any of its auxiliary files while one or + more instances of the realm are open, you might corrupt the realm or + disrupt :ref:`sync `. + + You may safely delete these files when all instances of a realm are + closed. Before you delete a realm file, make sure that you back up any + important objects as you will lose all unsynced data in the realm. diff --git a/source/sdk/react-native/realm-database/encrypt.txt b/source/sdk/react-native/realm-database/encrypt.txt index e9dab09106..4940d8da76 100644 --- a/source/sdk/react-native/realm-database/encrypt.txt +++ b/source/sdk/react-native/realm-database/encrypt.txt @@ -14,8 +14,7 @@ Overview -------- You can encrypt the realm database file on disk with AES-256 + -SHA-2 by supplying a 64-byte encryption key when :ref:`opening a -realm `. +SHA-2 by supplying a 64-byte encryption key when opening a realm. Realm transparently encrypts and decrypts data with standard :wikipedia:`AES-256 encryption ` using the diff --git a/source/sdk/react-native/realm-database/open-and-close-a-realm.txt b/source/sdk/react-native/realm-database/open-and-close-a-realm.txt deleted file mode 100644 index 3131d878a6..0000000000 --- a/source/sdk/react-native/realm-database/open-and-close-a-realm.txt +++ /dev/null @@ -1,82 +0,0 @@ -.. _react-native-open-close-realm: - -======================================= -Open & Close a Realm - React Native SDK -======================================= - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -Overview --------- -Realms are the core data structure used to organize data in Realm Database. At -its core, a realm is a collection of the objects that you use in your -application, called Realm objects, as well as additional metadata that describe -the objects. - -This page details how to configure and open a realm using the React Native SDK. - -.. _react-native-realm-file: - -Key Concept: Realm Files ------------------------- - -Realm Database stores a binary encoded version of every object and type in a -realm in a single ``.realm`` file. The file is located at a specific path that -you define when you open the realm. - -.. tip:: Implement Compacting in Your Production Application - - Every production application should implement a ``shouldCompactOnLaunch`` - callback to periodically reduce the realm file size. - -.. note:: Auxiliary Realm Files - - Realm Database creates additional files for each realm. - To learn more about these files, see :ref:`Realm Database Internals `. - -.. warning:: Use Caution When Deleting Realm Files - - In some circumstances, such as a client reset scenario, you might need to - delete a realm file and its auxiliary files. - - If you delete a realm file or any of its auxiliary files while one or - more instances of the realm are open, you might corrupt the realm or - disrupt :ref:`sync `. - - You may safely delete these files when all instances of a realm are - closed. Before you delete a realm file, make sure that you back up any - important objects as you will lose all unsynced data in the realm. - -.. _react-native-open-a-local-realm: - -Open a Local Realm ------------------- - -.. include:: /includes/js-open-a-local-realm.rst - -.. _react-native-open-an-in-memory-realm: - -Open an In Memory Realm ------------------------ - -.. include:: /includes/js-open-an-in-memory-realm.rst - -.. seealso:: Additional Ways to Configure a Realm - - - Learn how to :ref:`Open a Synced Realm ` - - Learn how to :ref:`Encrypt a Realm ` - - Learn how to :ref:`Bundle a Realm ` - - -.. _react-native-close-a-realm: - -Close a Realm -------------- - -.. include:: /includes/js-close-a-realm.rst - - diff --git a/source/sdk/react-native/realm-database/overview.txt b/source/sdk/react-native/realm-database/overview.txt index 028cf7e9df..7dc27f61af 100644 --- a/source/sdk/react-native/realm-database/overview.txt +++ b/source/sdk/react-native/realm-database/overview.txt @@ -65,8 +65,7 @@ your application without running a new query. Realm can support live objects because it :wikipedia:`memory-maps ` objects in your application directly to data stored in - the :ref:`realm file ` instead of a copy of the data - stored in memory. + the realm file instead of a copy of the data stored in memory. .. seealso::