آموزش Firebase و React-Native: Private Message App
در این آموزش، آنچه را که در طول سفرم برای آزمایش ساختن یک برنامه آزمایشی ساده ایجاد یک برنامه پیامرسان خصوصی یاد گرفتم، به شما نشان میدهم. من روند احراز هویت firebase موجود در برنامه را پوشش نمیدهم. این در پست قبلی در اینجا پوشش داده شد: https://dev.to/colinah/learning-firebase-and-react-native-authentication-2822.
در حالی که به راههایی برای ایجاد این موضوع فکر میکردم، میخواستم سیستم چت خصوصی را انعطافپذیر کنم، بنابراین اگر بخواهم آن چت را به یک چت گروهی تغییر دهم، معماری از قبل تنظیم شده بود. برای انجام این کار باید چند نکته را در نظر گرفت. اول اینکه چگونه دادهها را برای پیامها ذخیره میکنیم، به چه دادههایی نیاز داریم و چگونه کاربران را به آن دادهها متصل کنیم.
برای ذخیره پیامها، تصمیم گرفتم از مجموعه Firebase به نام اتاقها استفاده کنم، که دارای یک کلید منحصربهفرد است که از ترکیب دو شناسه کاربر ایجاد میشود. سپس سند اتاق حاوی ویژگیهای زیر، رنگ، آخرین پیام، پیامها و کاربران خواهد بود. در جایی که رنگ یک کد هگز رشته برای رنگی است که گروه را اختصاص می دهد، lastMessage آخرین پیامی است که در چت برای نمایش در صفحه لیست چت ها ارسال شده است، پیام ها مجموعه ای از پیام ها در اتاق هستند و در نهایت کاربران مجموعه ای از افراد در اتاق در اینجا نمونه ای از سند اتاق ها آورده شده است.
ما همچنین به راهی برای هر کاربر نیاز داریم تا بداند چه چت ها/اتاق هایی را قبلاً شروع به نمایش در صفحه پیام ها کرده است. من تصمیم گرفتم شناسه اتاق را در شی کاربر در یک آرایه ذخیره کنم.
اکنون که می دانیم پایگاه داده Firebase با این پروژه چگونه خواهد بود، اجازه دهید برنامه React-Native را شروع کنیم.
سه صفحه اصلی برای بخش چت برنامه، چت ها، پیام ها و newChat وجود دارد. صفحه چت لیستی از اتاق هایی را که کاربر در آن قرار دارد را نشان می دهد، صفحه پیام ها پیام های ارسال شده بین دو کاربر را نشان می دهد و در نهایت صفحه newChat به کاربر اجازه می دهد تا کاربرانی را برای شروع چت جستجو کند.
بیایید با ساخت صفحه چت شروع کنیم. ما می خواهیم در شیء کاربر firebase مشترک شویم تا در صورت تغییر، اتاق ها به طور خودکار به روز شوند. در اینجا کامپوننت Chats به نظر می رسد مولفه ChatGroup یک صفحه نمایش ساده است که نام افراد در چت و آخرین پیام را نشان می دهد.
export default function Chats() {
const [rooms, setRooms] = React.useState([]);
const { user } = useContext(UserContext);
const router = useRouter();
React.useEffect(() => {
const userRef = doc(firestore, 'users', user.uid);
const unSub = onSnapshot(userRef, (doc) => {
doc.exists() && setRooms(doc.data().rooms);
});
return () => {
unSub();
};
}, []);
return (
<View style={styles.container}>
<ScrollView>
{rooms ? (
rooms.map((room) => <ChatGroup roomId={room} key={room} />)
) : (
<View
style={{
padding: 6,
borderRadius: 6,
borderWidth: 1,
borderColor: '#ffffff60',
margin: 20,
}}>
<Text>You aren't in any rooms. Press the "+" to start a chat.</Text>
</View>
)}
</ScrollView>
<FAB icon="plus" style={styles.fab} onPress={() => router.push('/(chat)/newChat')} />
</View>
);
}
صفحه بعدی صفحه پیام ها است. برای افزودن عملکرد آسان تر، تصمیم گرفتم از بسته react-native-gifted-chat استفاده کنم که نمایش پیام ها را کنترل می کند. برای دریافت پیام ها باید به همان روشی که برای شی کاربر انجام دادیم، در سند اتاق ها مشترک شویم. این پیام ها را به روز نگه می دارد.
export default function Messages() {
const [messages, setMessages] = React.useState<IMessage[]>([]);
const { user } = React.useContext(UserContext);
const { id } = useSearchParams();
React.useEffect(() => {
const roomRef = doc(firestore, 'rooms', id as string);
const unSub = onSnapshot(roomRef, (doc) => {
doc.exists() &&
setMessages(
doc.data().messages.map((message: any) => ({
...message,
createdAt: message.createdAt.toDate(),
}))
);
});
return () => {
unSub();
};
}, [id]);
const onSend = async (messages: IMessage[]) => {
const roomRef = doc(firestore, 'rooms', id as string);
await updateDoc(roomRef, {
messages: arrayUnion(messages[0]),
lastMessage: messages[0],
});
};
return (
<View style={styles.container}>
<Stack.Screen
options={{
title: 'Messages',
}}
/>
<GiftedChat
renderBubble={ThemedBubble}
renderInputToolbar={ThemedInputToolbar}
minInputToolbarHeight={60}
messages={messages.reverse()}
showAvatarForEveryMessage
onSend={(messages) => onSend(messages)}
user={{
_id: user ? user.uid : 'Not logged it',
name: user ? (user.displayName as string) : 'No Display Name',
avatar: user?.photoURL ? user.photoURL : '',
}}
/>
</View>
);
}
در نهایت ما به راهی برای شروع چت های جدید با کاربران نیاز داریم، این در صفحه newChat انجام می شود. برای انجام این کار، ما فقط می توانیم یک ورودی جستجو داشته باشیم که به مجموعه کاربران متصل می شود و کاربران را با نام جستجو می کند.
export default function NewChat() {
const [search, setSearch] = React.useState('');
const [results, setResults] = React.useState<UserInfo[]>([]);
const onSearchHandler = async (text: string) => {
setSearch(text);
const q = query(collection(firestore, 'users'), where('displayName', '==', text.toLowerCase()));
try {
const querySnapshot = await getDocs(q);
const list = [] as UserInfo[];
querySnapshot.forEach((doc) => list.push(doc.data() as UserInfo));
setResults(list);
} catch (err) {
console.log('error', err);
}
};
return (
<View style={{ flex: 1 }}>
<TextInput value={search} onChangeText={onSearchHandler} />
{results.map((user) => (
<SearchResult username={user.displayName} email={user.email} id={user.uid} key={user.uid} />
))}
</View>
);
}
این چارچوب اساسی برای ساخت یک برنامه پیامرسان خصوصی با استفاده از react native و firebase است. اگر میخواهید کل پروژه را ببینید، میتوانید آن را در اینجا در https://github.com/codingcruxes/react-native-firebase-chat پیدا کنید.
امیدوارم از دنبال کردن آن لذت برده باشید و بتوانید به اندازه من در طول این فرآیند یاد بگیرید.