From 35004c92b52adbf4a25d3eab7301d161bad320d2 Mon Sep 17 00:00:00 2001 From: LJ <81748770+elle-j@users.noreply.github.com> Date: Tue, 31 Oct 2023 13:57:33 +0100 Subject: [PATCH] Additions to custom user data (#6221) --- examples/rn-connection-and-error/README.md | 23 ++++++++++++++---- .../AuthExample/Users/rules.json | 22 +++++++++++++++++ .../backend/functions/config.json | 1 - .../backend/functions/onUserCreation.js | 4 ++-- .../frontend/app/screens/StoreScreen.tsx | 24 ++++++++++++++----- 5 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 examples/rn-connection-and-error/backend/data_sources/mongodb-atlas/AuthExample/Users/rules.json diff --git a/examples/rn-connection-and-error/README.md b/examples/rn-connection-and-error/README.md index e06a9f1a7b..dc73283497 100644 --- a/examples/rn-connection-and-error/README.md +++ b/examples/rn-connection-and-error/README.md @@ -72,7 +72,7 @@ It specifically addresses the following points: * With non-existent email * Listening (and triggering) when a user gets logged out. * Listening (and triggering) when a user gets removed. -* Listening (and triggering) when a user's tokens are refreshed. +* Listening (and triggering) when a user's tokens and custom data are refreshed. * Listening (and triggering) when the underlying sync session: * Tries to connect * Gets connected @@ -202,17 +202,21 @@ To sync data used in this app you must first: ### Add an Atlas Function -> If you set up your App Services App [via a CLI](#via-a-cli-recommended), you can **skip this step** as the function should already be defined for you. +> If you set up your App Services App [via a CLI](#via-a-cli-recommended), you can **skip this step** as these functions should already be defined for you. -We will add a function for forcing a client reset. The function is solely used for demo purposes and should not be used in production. +We will add a function for forcing a client reset. The function is solely used for demo purposes and should not be used in production. We will also add a function to be run on user creation that adds fields to the user's [custom user data](https://www.mongodb.com/docs/atlas/app-services/users/custom-metadata/) document. To set this up via the App Services UI: -1. [Define a function](https://www.mongodb.com/docs/atlas/app-services/functions/#define-a-function) with the following configurations: +1. [Define two functions](https://www.mongodb.com/docs/atlas/app-services/functions/#define-a-function) with the following configurations: * Function name: `triggerClientReset` * Authentication: `System` * Private: `false` * Code: See [backend function](./backend/functions/triggerClientReset.js) + * Function name: `onUserCreation` + * Authentication: `Application Authentication` + * Private: `false` + * Code: See [backend function](./backend/functions/onUserCreation.js) ### Install Dependencies @@ -254,7 +258,16 @@ npm run android > If you set up your App Services App [via a CLI](#via-a-cli-recommended), you can **skip this step** as the permissions should already be defined for you. -After running the client app for the first time, [check the rules](https://www.mongodb.com/docs/atlas/app-services/rules/roles/#define-roles---permissions) for the collections in the App Services UI and make sure all collections have `readAndWriteAll` permissions (see [corresponding json](./backend/data_sources/mongodb-atlas/sync/Product/rules.json)). +After running the client app for the first time, [modify the rules](https://www.mongodb.com/docs/atlas/app-services/rules/roles/#define-roles---permissions) for the collections in the App Services UI. + +* Collections: `Kiosk`, `Product`, `Store` + * Permissions: `readAndWriteAll` (see [corresponding json](./backend/data_sources/mongodb-atlas/sync/Product/rules.json)) + * Explanation: + * All users will be able to read and write to the above collections. +* Collection: `Users` + * Permissions: `ThisUser` (see [corresponding json](./backend/data_sources/mongodb-atlas/AuthExample/Users/rules.json)) + * Explanation: + * Users who have registered each have a `Users` document as custom user data. A user will be able to read and write to their own document (i.e. when `Users.user_id === `), but not anyone else's (see [Secure Custom User Data](https://www.mongodb.com/docs/atlas/app-services/users/custom-metadata/#secure-custom-user-data)). > To learn more and see examples of permissions depending on a certain use case, see [Device Sync Permissions Guide](https://www.mongodb.com/docs/atlas/app-services/sync/app-builder/device-sync-permissions-guide/#std-label-flexible-sync-permissions-guide) and [Data Access Role Examples](https://www.mongodb.com/docs/atlas/app-services/rules/examples/). diff --git a/examples/rn-connection-and-error/backend/data_sources/mongodb-atlas/AuthExample/Users/rules.json b/examples/rn-connection-and-error/backend/data_sources/mongodb-atlas/AuthExample/Users/rules.json new file mode 100644 index 0000000000..0176ecaac0 --- /dev/null +++ b/examples/rn-connection-and-error/backend/data_sources/mongodb-atlas/AuthExample/Users/rules.json @@ -0,0 +1,22 @@ +{ + "collection": "Users", + "database": "AuthExample", + "roles": [ + { + "name": "ThisUser", + "apply_when": { + "user_id": "%%user.id%%" + }, + "document_filters": { + "write": {}, + "read": {} + }, + "read": true, + "write": true, + "insert": false, + "delete": false, + "search": false + } + ], + "filters": [] +} diff --git a/examples/rn-connection-and-error/backend/functions/config.json b/examples/rn-connection-and-error/backend/functions/config.json index 5d5b38f1bd..526d5d60f2 100644 --- a/examples/rn-connection-and-error/backend/functions/config.json +++ b/examples/rn-connection-and-error/backend/functions/config.json @@ -8,7 +8,6 @@ { "name": "onUserCreation", "private": false, - "run_as_system": true, "disable_arg_logs": true } ] diff --git a/examples/rn-connection-and-error/backend/functions/onUserCreation.js b/examples/rn-connection-and-error/backend/functions/onUserCreation.js index 0653782de0..dc8b363335 100644 --- a/examples/rn-connection-and-error/backend/functions/onUserCreation.js +++ b/examples/rn-connection-and-error/backend/functions/onUserCreation.js @@ -7,9 +7,9 @@ exports = async function onUserCreation(user) { const customUserDataCollection = context.services.get("mongodb-atlas").db("AuthExample").collection("Users"); try { await customUserDataCollection.insertOne({ - // Save the user's account ID to your configured user_id_field + // Save the user's account ID to your configured user_id field. user_id: user.id, - // Store any other user data you want + // Store any other user data you want. team: "service", }); } catch (e) { diff --git a/examples/rn-connection-and-error/frontend/app/screens/StoreScreen.tsx b/examples/rn-connection-and-error/frontend/app/screens/StoreScreen.tsx index 647dde6d56..ed62cb9632 100644 --- a/examples/rn-connection-and-error/frontend/app/screens/StoreScreen.tsx +++ b/examples/rn-connection-and-error/frontend/app/screens/StoreScreen.tsx @@ -27,6 +27,18 @@ import {fonts} from '../styles/fonts'; import {useDemoSyncTriggers} from '../hooks/useDemoSyncTriggers'; import {useStore} from '../providers/StoreProvider'; +/** + * The properties used as custom user data. + * + * @note + * Our backend function `onUserCreation()` adds these fields + * when the user registers. + */ +type CustomUserData = { + user_id: string; + team: string; +}; + /** * Screen for showing the kiosks and products in the store, * as well as buttons for triggering various listeners. @@ -44,7 +56,7 @@ export function StoreScreen() { deleteUser, } = useDemoSyncTriggers(); const {logOut} = useAuth(); - const user = useUser(); + const user = useUser<{}, CustomUserData, {}>(); return ( @@ -72,6 +84,11 @@ export function StoreScreen() { /> + + + Team: {user.customData.team} + + Status: {isConnected ? 'Connected 🟢' : 'Not connected 🔴'} @@ -82,11 +99,6 @@ export function StoreScreen() { text={isConnected ? 'Disconnect' : 'Connect'} /> - - - Team: {user.customData?.team || '-'} - -