import { QuickSqliteClient } from "stream-chat-react-native";
const logout = async () => {
// Reset and clear the local database if offline storage was enabled.
QuickSqliteClient.resetDB();
// Disconnect the connected user for the chat client.
chatClient?.disconnectUser();
// Set the current chat client to null.
setChatClient(null);
};Going Live Checklist
Before going live, check the following to launch smoothly.
Best Practices
- Replace development tokens with server-issued, expiring user tokens.
- Never ship secrets or API keys in the client app.
- Reset offline storage before switching users to avoid data leaks.
- Profile custom components for re-render hotspots in message lists.
- Validate permissions and notifications across both platforms.
Usage of Tokens
Development tokens are fine for local testing, but they disable auth and are not for production. Use proper auth before release. For extra security, use expiring tokens and a token provider to refresh them.
Sensitive Data Storage
Never store secrets (like your Stream secret) on-device. A compromised device can expose them and allow destructive actions.
Logging out
If you use offline storage, clear it on logout and wait for logout to complete before switching users. Otherwise you can corrupt state or crash.
Performance for Custom components
When a context value updates, all consumers re-render. Our components use memoization and custom areEqual checks to reduce unnecessary re-renders, especially in message lists. Apply the same pattern in custom components.
Example: a component reading PaginatedMessageListContext will re-render often:
import { usePaginatedMessageListContext } from "stream-chat-react-native";
import { Text } from "react-native";
const MySenderComponent = () => {
const { messages } = usePaginatedMessageListContext();
const latestMessageSender = messages[messages.length - 1]?.user?.name;
console.log("Render.");
return <Text>{`Last Sender: ${latestMessageSender}`}</Text>;
};Reduce re-renders by splitting context access from a memoized presentational component with a custom areEqual:
import React from "react";
import { usePaginatedMessageListContext } from "stream-chat-react-native";
import { Text } from "react-native";
const MySenderComponentWithContext = ({ latestMessageSender }) => {
console.log("Rendered");
return <Text>{`Last Sender: ${latestMessageSender}`}</Text>;
};
const MemoizedMySenderComponent = React.memo(
MySenderComponentWithContext,
(prev, next) => prev.latestMessageSender === next.latestMessageSender,
);
const MySenderComponent = () => {
const { messages } = usePaginatedMessageListContext();
const latestMessageSender = messages[messages.length - 1]?.user?.name;
return (
<MemoizedMySenderComponent latestMessageSender={latestMessageSender} />
);
};With this pattern, the Text component renders on mount and only updates when latestMessageSender changes.