Skip to content

Commit b55a242

Browse files
authored
TRON-10: Async Storage not Required (#1464)
## Please verify the following: - [x] `yarn build-and-test:local` passes - [ ] I have added tests for any new features, if relevant - [ ] `README.md` (or relevant documentation) has been updated with your changes ## Describe your PR When an application does not have Async Storage or other persistent storage mechanism configured, Reactotron will create a new connection and device each time the application is reloaded. ### Reproduce Behavior Use the example application inside of the project and comment out line 8: ``` // import AsyncStorage from "@react-native-async-storage/async-storage" ``` and line 36: ``` // reactotron.setAsyncStorageHandler?.(AsyncStorage) ``` This will deactivate Async Storage and no longer persist the generated unique `clientId` coming from the websocket server. ### Research & Constraints * Reactotron currently works with Expo Go. In order to maintain that support, we cannot use packages like `react-native-device-info` as it has native components that would need to be installed. * `expo-device` did not provide any additional functionality on top of what we already had access to. * Websocks do have a unique key, but we'd have to store that key on the device... * Device orientation should not change `clientId`. (thanks @frankcalise) * Switching applications on the same simulator should not mingle their timelines. ### Solution When Async Storage or the like is not configured, generate a device fingerprint as a _best effort_ to keep the connected devices stable. This seems like a good enough solution as there are no additional dependencies and working with information that we already had. | Before | After | |--------|--------| | <video src="https://github.com/infinitered/reactotron/assets/151139/5c18642b-121f-41cf-9864-e32a1019dc1a" /> | <video src="https://github.com/infinitered/reactotron/assets/151139/264eedfd-65e8-4781-9d5d-d55006138b53" /> | ## Additional Notes Do we have documentation in Reactotron for configuring MMKV or Expo SecureStore?
1 parent 8226fdf commit b55a242

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

lib/reactotron-core-client/src/client-options.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export interface ClientOptions<Client> extends LifeCycleMethods {
8585
/**
8686
* Get the client id provided by the server
8787
*/
88-
getClientId?: () => Promise<string>
88+
getClientId?: (name: string) => Promise<string>
8989

9090
proxyHack?: boolean
9191
}

lib/reactotron-core-client/src/reactotron-core-client.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ export class ReactotronImpl implements ReactotronCore {
282282

283283
const getClientIdPromise = getClientId || emptyPromise
284284

285-
getClientIdPromise().then((clientId) => {
285+
getClientIdPromise(name).then((clientId) => {
286286
this.isReady = true
287287
// introduce ourselves
288288
this.send("client.intro", {

lib/reactotron-react-native/src/reactotron-react-native.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,29 @@ const DEFAULTS: ClientOptions<ReactotronReactNative> = {
6565
...getReactNativeDimensions(),
6666
},
6767
/* eslint-disable @typescript-eslint/no-use-before-define */
68-
getClientId: async () => {
68+
getClientId: async (name: string = "") => {
6969
if (reactotron.asyncStorageHandler) {
7070
return reactotron.asyncStorageHandler.getItem(REACTOTRON_ASYNC_CLIENT_ID)
7171
}
7272

73+
// Generate clientId based on the device info
74+
const { screenWidth, screenHeight, screenScale } = getReactNativeDimensions()
75+
76+
// Accounting for screen rotation
77+
const dimensions = [screenWidth, screenHeight].sort().join("-")
78+
79+
tempClientId = [
80+
name,
81+
Platform.OS,
82+
Platform.Version,
83+
constants.systemName,
84+
constants.Model,
85+
dimensions,
86+
screenScale,
87+
]
88+
.filter(Boolean)
89+
.join("-")
90+
7391
return tempClientId
7492
},
7593
setClientId: async (clientId: string) => {

0 commit comments

Comments
 (0)