Skip to content

Commit ffbb8fc

Browse files
committed
feat: support mmkv storage and deprecate a async storage
1 parent 0e32587 commit ffbb8fc

File tree

20 files changed

+196
-94
lines changed

20 files changed

+196
-94
lines changed

docs-validation/1_introduction/SendYourFirstMessage.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ export const platformServices: SendbirdUIKitContainerProps['platformServices'] =
6161
* {@link https://sendbird.com/docs/chat/uikit/v3/react-native/introduction/send-first-message#2-get-started-3-step-5-wrap-your-app-in-sendbirduikitcontainer}
6262
* */
6363
import { SendbirdUIKitContainer } from '@sendbird/uikit-react-native';
64-
import AsyncStorage from '@react-native-async-storage/async-storage';
64+
import { MMKV } from 'react-native-mmkv';
65+
66+
const mmkv = new MMKV();
6567

6668
const App = () => {
6769
return (
6870
<SendbirdUIKitContainer
6971
appId={'APP_ID'}
70-
chatOptions={{ localCacheStorage: AsyncStorage }}
72+
chatOptions={{ localCacheStorage: mmkv }}
7173
platformServices={platformServices}
7274
>
7375
{/* Rest of your app */}
@@ -186,7 +188,7 @@ const App2 = () => {
186188
return (
187189
<SendbirdUIKitContainer
188190
appId={'APP_ID'}
189-
chatOptions={{ localCacheStorage: AsyncStorage }}
191+
chatOptions={{ localCacheStorage: mmkv }}
190192
platformServices={platformServices}
191193
>
192194
<Navigation />

docs-validation/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
},
1010
"dependencies": {
1111
"@bam.tech/react-native-image-resizer": "^3.0.4",
12-
"@react-native-async-storage/async-storage": "^1.15.17",
1312
"@react-native-camera-roll/camera-roll": "^5.4.0",
1413
"@react-native-clipboard/clipboard": "^1.8.5",
1514
"@react-native-firebase/messaging": "^14.7.0",
1615
"@react-navigation/native": "^6.0.6",
1716
"@react-navigation/native-stack": "^6.7.0",
18-
"@sendbird/chat": "^4.10.7",
17+
"@sendbird/chat": "^4.12.8",
1918
"react": "18.2.0",
2019
"react-native": "0.74.3",
2120
"react-native-create-thumbnail": "^2.0.0",
2221
"react-native-document-picker": "^8.0.0",
2322
"react-native-file-access": "^2.5.0",
2423
"react-native-image-picker": "^4.7.3",
24+
"react-native-mmkv": "^2.0.0",
2525
"react-native-permissions": "^3.6.0",
2626
"react-native-safe-area-context": "^3.3.2",
2727
"react-native-video": "^5.2.0"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
]
9999
},
100100
"resolutions": {
101-
"@sendbird/chat": "4.11.3",
101+
"@sendbird/chat": "4.12.8",
102102
"@types/react": "^18"
103103
}
104104
}

packages/uikit-chat-hooks/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"typescript": "5.2.2"
5656
},
5757
"peerDependencies": {
58-
"@sendbird/chat": "^4.10.7",
58+
"@sendbird/chat": "^4.12.8",
5959
"react": ">=16.13.1"
6060
},
6161
"react-native-builder-bob": {

packages/uikit-react-native/README.md

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,15 @@ UIKit for React-Native can be installed through either `yarn` or `npm`
4646

4747
**Install dependencies**
4848

49-
> Note: If you are using `react-native` version `0.72` or higher, you don't need to install `@sendbird/react-native-scrollview-enhancer`.
49+
> Note: If you are using `react-native` version `0.71` or lower, you should install `@sendbird/react-native-scrollview-enhancer`.
5050
5151
```sh
5252
npm install @sendbird/uikit-react-native \
5353
@sendbird/chat \
54-
@sendbird/react-native-scrollview-enhancer \
5554
date-fns \
5655
react-native-safe-area-context \
5756
@react-native-community/netinfo \
58-
@react-native-async-storage/async-storage
57+
react-native-mmkv
5958
```
6059

6160
**Linking native modules**
@@ -116,7 +115,7 @@ const App = () => {
116115
<SendbirdUIKitContainer
117116
appId={'APP_ID'}
118117
chatOptions={{
119-
localCacheStorage: AsyncStorage,
118+
localCacheStorage: MMKV,
120119
}}
121120
platformServices={{
122121
file: FileService,
@@ -257,45 +256,30 @@ const expoPlatformServices = {
257256
You can implement Local caching easily.
258257

259258
```shell
260-
npm i @react-native-async-storage/async-storage
259+
npm i react-native-mmkv
261260
npx pod-install
262261
```
263262

264263
```tsx
265-
import AsyncStorage from '@react-native-async-storage/async-storage';
264+
import { MMKV } from 'react-native-mmkv';
266265

267266
import { SendbirdUIKitContainer } from '@sendbird/uikit-react-native';
268267

268+
const mmkv = new MMKV();
269269
const App = () => {
270-
return <SendbirdUIKitContainer chatOptions={{ localCacheStorage: AsyncStorage }}>{/* ... */}</SendbirdUIKitContainer>;
270+
return <SendbirdUIKitContainer chatOptions={{ localCacheStorage: mmkv }}>{/* ... */}</SendbirdUIKitContainer>;
271271
};
272272
```
273273

274-
Or you can use storage you are using instead of `AsyncStorage` (e.g. [`react-native-mmkv`](https://github.com/mrousavy/react-native-mmkv))
274+
Or you can use `AsyncStorage` instead of `MMKV`, but it has been deprecated.
275275

276276
```tsx
277-
import { MMKV } from 'react-native-mmkv';
277+
import { AsyncStorage } from '@react-native-async-storage/async-storage';
278278

279-
import { LocalCacheStorage, SendbirdUIKitContainer } from '@sendbird/uikit-react-native';
280-
281-
const mmkvStorage = new MMKV();
282-
const localCacheStorage: LocalCacheStorage = {
283-
async getAllKeys() {
284-
return mmkvStorage.getAllKeys();
285-
},
286-
async setItem(key: string, value: string) {
287-
return mmkvStorage.set(key, value);
288-
},
289-
async getItem(key: string) {
290-
return mmkvStorage.getString(key) ?? null;
291-
},
292-
async removeItem(key: string) {
293-
return mmkvStorage.delete(key);
294-
},
295-
};
279+
import { SendbirdUIKitContainer } from '@sendbird/uikit-react-native';
296280

297281
const App = () => {
298-
return <SendbirdUIKitContainer chatOptions={{ localCacheStorage }}>{/* ... */}</SendbirdUIKitContainer>;
282+
return <SendbirdUIKitContainer chatOptions={{ localCacheStorage: AsyncStorage }}>{/* ... */}</SendbirdUIKitContainer>;
299283
};
300284
```
301285

packages/uikit-react-native/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"react-native-document-picker": "^8.0.0",
9797
"react-native-file-access": "^2.5.0",
9898
"react-native-image-picker": "^4.7.1",
99+
"react-native-mmkv": "^2.12.2",
99100
"react-native-permissions": "^3.6.0",
100101
"react-native-safe-area-context": "^3.3.2",
101102
"react-native-video": "^5.2.0",
@@ -107,7 +108,7 @@
107108
"@react-native-clipboard/clipboard": ">=1.8.5",
108109
"@react-native-community/netinfo": ">=9.3.0",
109110
"@react-native-firebase/messaging": ">=14.4.0",
110-
"@sendbird/chat": "^4.10.7",
111+
"@sendbird/chat": "^4.12.8",
111112
"@sendbird/react-native-scrollview-enhancer": "*",
112113
"date-fns": ">=2.28.0",
113114
"expo-av": ">=12.0.4",
@@ -125,6 +126,7 @@
125126
"react-native-document-picker": ">=8.0.0",
126127
"react-native-file-access": ">=2.4.3",
127128
"react-native-image-picker": ">=4.7.1",
129+
"react-native-mmkv": "^2.0.0",
128130
"react-native-permissions": ">=3.6.0",
129131
"react-native-safe-area-context": ">=3.3.2",
130132
"react-native-video": ">=5.2.0"

packages/uikit-react-native/src/containers/SendbirdUIKitContainer.tsx

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,17 @@ import {
1515
UIKitThemeProvider,
1616
} from '@sendbird/uikit-react-native-foundation';
1717
import { SBUConfig, UIKitConfigProvider } from '@sendbird/uikit-tools';
18-
import type {
18+
import {
19+
Logger,
20+
NOOP,
1921
PartialDeep,
2022
SendbirdChatSDK,
2123
SendbirdGroupChannel,
2224
SendbirdGroupChannelCreateParams,
2325
SendbirdMember,
2426
SendbirdUser,
27+
useIsFirstMount,
2528
} from '@sendbird/uikit-utils';
26-
import { NOOP, useIsFirstMount } from '@sendbird/uikit-utils';
2729

2830
import { LocalizationContext, LocalizationProvider } from '../contexts/LocalizationCtx';
2931
import { PlatformServiceProvider } from '../contexts/PlatformServiceCtx';
@@ -50,7 +52,7 @@ import type {
5052
PlayerServiceInterface,
5153
RecorderServiceInterface,
5254
} from '../platform/types';
53-
import type { ErrorBoundaryProps, LocalCacheStorage } from '../types';
55+
import { ErrorBoundaryProps, LocalCacheStorage } from '../types';
5456
import VERSION from '../version';
5557
import InternalErrorBoundaryContainer from './InternalErrorBoundaryContainer';
5658

@@ -78,13 +80,13 @@ const chatOmitKeys = [
7880
'appVersion',
7981
'localCacheEnabled',
8082
'useAsyncStorageStore',
83+
'useMMKVStorageStore',
8184
] as const;
8285
function sanitizeChatOptions<T extends Record<string, unknown>>(chatOptions: T): T {
8386
const opts = { ...chatOptions };
8487
chatOmitKeys.forEach((key) => delete opts[key]);
8588
return opts;
8689
}
87-
8890
export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
8991
appId: string;
9092
platformServices: {
@@ -95,11 +97,11 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
9597
player: PlayerServiceInterface;
9698
recorder: RecorderServiceInterface;
9799
};
98-
chatOptions: {
99-
localCacheStorage: LocalCacheStorage;
100-
onInitialized?: (sdkInstance: SendbirdChatSDK) => SendbirdChatSDK;
101-
} & Partial<ChatOmittedInitParams> &
102-
Partial<ChatRelatedFeaturesInUIKit>;
100+
chatOptions: Partial<ChatOmittedInitParams> &
101+
Partial<ChatRelatedFeaturesInUIKit> & {
102+
onInitialized?: (sdkInstance: SendbirdChatSDK) => SendbirdChatSDK;
103+
localCacheStorage: LocalCacheStorage;
104+
};
103105
uikitOptions?: PartialDeep<{
104106
common: SBUConfig['common'];
105107
groupChannel: Omit<SBUConfig['groupChannel']['channel'], 'enableReactionsSupergroup'> & {
@@ -162,6 +164,10 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
162164

163165
if (!chatOptions.localCacheStorage) {
164166
throw new Error('SendbirdUIKitContainer: chatOptions.localCacheStorage is required');
167+
} else if ('getItem' in chatOptions.localCacheStorage) {
168+
Logger.warn(
169+
'SendbirdUIKitContainer: localCacheStorage for `AsyncStorage` is deprecated. Please use `MMKV` instead.',
170+
);
165171
}
166172

167173
const defaultStringSet = localization?.stringSet ?? StringSetEn;
@@ -171,7 +177,7 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
171177

172178
const [internalStorage] = useState(() => new InternalLocalCacheStorage(chatOptions.localCacheStorage));
173179
const [sdkInstance, setSdkInstance] = useState<SendbirdChatSDK>(() => {
174-
const sendbird = initializeSendbird(appId, { internalStorage, ...sanitizeChatOptions(chatOptions) });
180+
const sendbird = initializeSendbird(appId, sanitizeChatOptions(chatOptions));
175181
unsubscribes.current = sendbird.unsubscribes;
176182
return sendbird.chatSDK;
177183
});
@@ -183,7 +189,7 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
183189

184190
useLayoutEffect(() => {
185191
if (!isFirstMount) {
186-
const sendbird = initializeSendbird(appId, { internalStorage, ...sanitizeChatOptions(chatOptions) });
192+
const sendbird = initializeSendbird(appId, sanitizeChatOptions(chatOptions));
187193
setSdkInstance(sendbird.chatSDK);
188194
unsubscribes.current = sendbird.unsubscribes;
189195
}
@@ -288,21 +294,23 @@ const SendbirdUIKitContainer = (props: SendbirdUIKitContainerProps) => {
288294
};
289295

290296
interface InitOptions extends ChatOmittedInitParams {
291-
internalStorage: InternalLocalCacheStorage;
297+
localCacheStorage: LocalCacheStorage;
292298
onInitialized?: (sdk: SendbirdChatSDK) => SendbirdChatSDK;
293299
}
294300
const initializeSendbird = (appId: string, options: InitOptions) => {
295301
let chatSDK: SendbirdChatSDK;
296302
const unsubscribes: Array<() => void> = [];
297-
const { internalStorage, onInitialized, ...chatInitParams } = options;
303+
const { localCacheStorage, onInitialized, ...chatInitParams } = options;
298304

305+
const isMMKVStorage = 'getString' in localCacheStorage;
299306
chatSDK = SendbirdChat.init({
300307
...chatInitParams,
301308
appId,
302309
newInstance: true,
303310
modules: [new GroupChannelModule(), new OpenChannelModule()],
304311
localCacheEnabled: true,
305-
useAsyncStorageStore: internalStorage as never,
312+
useMMKVStorageStore: isMMKVStorage ? (localCacheStorage as never) : undefined,
313+
useAsyncStorageStore: !isMMKVStorage ? (localCacheStorage as never) : undefined,
306314
});
307315

308316
if (onInitialized) {

packages/uikit-react-native/src/libs/EmojiManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { SendbirdEmoji, SendbirdEmojiCategory, SendbirdEmojiContainer } from '@sendbird/uikit-utils';
22

3-
import type { LocalCacheStorage } from '../types';
3+
import type { AsyncLocalCacheStorage } from '../types';
44
import InternalLocalCacheStorage from './InternalLocalCacheStorage';
55

6-
class MemoryStorage implements LocalCacheStorage {
6+
class MemoryStorage implements AsyncLocalCacheStorage {
77
_data: Record<string, string> = {};
88

99
async getAllKeys(): Promise<readonly string[] | string[]> {

0 commit comments

Comments
 (0)