Offline Support
React Native Chat SDK provides OOTB support for offline mode, which means user will be able to access and interact with chat even when the network is off. This is an opt-in feature that needs to be explicitly enabled on application level.
Integration with Expo is possible using the expo-dev-client
library. Offline support cannot be used in the "Expo Go" app, because it requires custom native code.
Features
The offline storage implementation currently offers the following features:
- Access to chat when Internet connection is disabled or low.
- Faster startup times and loading, since initial data is loaded from offline storage before performing any network requests.
- Syncing of the offline database using WebSocket events and Sync API.
- Optimistically update offline database during chat interactions, such as send message, add reaction, etc.
The following features are currently NOT implemented. They will be implemented gradually as part of minor releases in v5.
- Access to threads in offline mode.
Enable Offline Support
First and foremost, make sure to follow all steps from Migrating to v5 guide. To enable offline support, please follow the given steps:
Add react-native-quick-sqlite
dependency.
Contemplate our dependency version compatibility table to make sure your
react-native-quick-sqlite
version are compatible with yourstream-chat-react-native
version.
yarn add react-native-quick-sqlite
npx pod-install
Do not wait for connectUser
call to succeed.
It is important that you call the connectUser
method on the chat client, before you render Chat components. But you don't need to wait for connectUser
to succeed before rendering Chat components. This is to ensure:
- Chat components have access to current user information, which is important to store/access offline data.
- In case of slow or no network access, Chat components will still load the chat data without waiting for
connectUser
to succeed.
const chatClient = StreamChat.getInstance('API_KEY');
const App = () => {
const [isClientReady, setIsClientReady] = useState(false);
useEffect(() => {
const startChat = async () => {
const connectPromise = chatClient.connectUser(user, tokenOrTokenProvider);
setIsClientReady(true); // this allows components to render
await connectPromise();
// Any other post-connectUser logic you may have goes here.
};
startChat();
}, []);
if (!isClientReady) return null; // or some loading indicator;
return (
<Chat client={chatClient} enableOfflineSupport>
...
</Chat>
);
};
Add enableOfflineSupport
prop on Chat
component.
import { Chat } from 'stream-chat-react-native';
<Chat client={chatClient} enableOfflineSupport>
...
</Chat>;
Reset the database when signing out the user.
Since the SDK doesn't handle app-level authentication logic, it's the application's responsibility to ensure the database is reset when a user gets logged out. This should generally be done before you call client.disconnectUser()
.
import { QuickSqliteClient } from 'stream-chat-react-native';
// Sign out logic
QuickSqliteClient.resetDB();
chatClient.disconnectUser();
How To Cache Images
Available since version 5.3.0
Our SDK relies on the default caching provided by React Native (avatars, image attachments, URL preview, etc.). This default solution is far from perfect, and you might see a lot of images missing while operating the app in offline mode. We provide a convenient solution to replace all the underlying usage of the Image
component using the ImageComponent
prop on the Chat
component. Use the ImageComponent
prop to provide a custom component that handles caching and has the same API as react-native's Image
component.
There are plenty of libraries available for this purpose:
Due to technical limitations, viewing images in full screen (image viewer) in offline mode is not currently supported.
The following example demonstrates the usage of react-native-fast-image
library to handle the caching of images in chat:
import FastImage from 'react-native-fast-image';
...
<Chat
client={chatClient}
enableOfflineSupport
ImageComponent={FastImage}
/>