Skip to content

Instantly share code, notes, and snippets.

@keith-kurak
Last active December 29, 2021 20:42
Show Gist options
  • Save keith-kurak/cc30f0e72d0239de14a71bfa43ce9fdf to your computer and use it in GitHub Desktop.
Save keith-kurak/cc30f0e72d0239de14a71bfa43ce9fdf to your computer and use it in GitHub Desktop.
05: Hello, Chat!
Follow these steps to add chat to each channel
// add sendMessage
const sendMessage = flow(function* sendMessage({ text, channelId }) {
const db = getFirestore();
// add new document with auto-id
yield addDoc(
const channelsCollection = collection(db, "channels");
const channelDoc = doc(channelsCollection, channelId);
const messagesCollection = collection(channelDoc, "messages");
messagesCollection,
{
text,
time: serverTimestamp(),
username: self.user.email,
uid: self.user.uid,
}
);
});
// call sendMessage in onSendMessage
onSendMessage={(text) => rootStore.sendMessage({ text, channelId: route.params.channelId })
// add streaming of messages into store
// create Message model
const Message = types.model("Message", {
id: types.string,
uid: types.string,
username: types.string,
time: types.number,
text: types.string,
});
// add messages to RootStore model
messages: types.optional(types.array(Message), []),
// stream messsages to the messages prop
let unsubscribeFromChannelMessagesFeed;
const startStreamingChannelMessages = (channelId) => {
const db = getFirestore();
const channelsCollection = collection(db, "channels");
const channelDoc = doc(channelsCollection, channelId);
const messagesCollection = collection(channelDoc, "messages");
const q = query(messagesCollection);
unsubscribeFromChannelMessagesFeed = onSnapshot(q, (querySnapshot) => {
self.updateMessages(querySnapshot);
});
};
const stopStreamingCurrentChannel = () => {
self.messages = [];
unsubscribeFromChannelMessagesFeed();
};
// add semi-private function to update messages prop
const updateMessages = (querySnapshot) => {
self.messages = [];
querySnapshot.forEach((doc) => {
const data = doc.data();
self.messages.push({
id: doc.id,
uid: data.uid,
username: data.username,
// when message is added locally before upload, time is null because it will
// later be set by the server
time: data.time ? data.time.seconds * 1000 : new Date().getTime(),
text: data.text,
});
});
};
// remove mocks, set messages to rootStore.messages
messages={rootStore.messages}
// also add subscription to useEffect
useEffect(() => {
rootStore.startStreamingChannelMessages(route.params.channelId);
return rootStore.stopStreamingCurrentChannel;
}, []);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment