moved chats to realtime database

pull/3/head
Simon Huang 5 years ago
parent fe1934d7b3
commit 92489bd96b

@ -8,19 +8,6 @@
// Firestore
const collection = {
chats: [
{
roomId: {
messages: [
{
content: 'Message content',
createdAt: 'timestamp',
senderId: 'userId',
},
],
},
},
],
playlists: [
{
roomId: {
@ -71,6 +58,17 @@ const turtle = {
},
},
// Keep chats in Realtime DB could potentially lower cost
chats: {
roomId: {
messageId: {
content: 'Message content',
senderId: 'userId',
createdAt: 'timestamp',
},
},
},
// Keeping track of which users are present in a room
rooms: {
roomId: {

@ -1,7 +1,7 @@
import { IonCard, IonFabButton, IonFooter, IonIcon, IonInput, IonToolbar } from '@ionic/react';
import { sendOutline } from 'ionicons/icons';
import React, { useState } from 'react';
import { db, arrayUnion } from '../services/firebase';
import { rtdb } from '../services/firebase';
import './Chatbox.css';
import Messages from './Messages';
import OnlineList from './OnlineList';
@ -19,16 +19,11 @@ const Chat: React.FC<ChatboxProps> = ({ ownerId, roomId, userId, userList }) =>
// Send message to database
const sendMessage = async () => {
if (message !== '') {
await db
.collection('chats')
.doc(roomId)
.update({
messages: arrayUnion({
createdAt: Date.now(),
senderId: userId,
content: message,
}),
});
await rtdb.ref('/chats/' + roomId).push({
content: message,
createdAt: Date.now(),
senderId: userId,
});
// Reset textarea field
setMessage('');

@ -1,6 +1,6 @@
import { IonCol, IonContent, IonGrid, IonRow } from '@ionic/react';
import React, { useEffect, useRef, useState } from 'react';
import { db, arrayUnion } from '../services/firebase';
import { db, arrayUnion, rtdb } from '../services/firebase';
import './Messages.css';
import { secondsToTimestamp } from '../services/utilities';
@ -37,31 +37,22 @@ const Messages: React.FC<MessagesProps> = ({ ownerId, roomId, userId, userList }
// Listen for new chat messages
useEffect(() => {
const chatUnsubscribe = db
.collection('chats')
.doc(roomId)
.onSnapshot((docSnapshot) => {
const data = docSnapshot.data();
if (data !== undefined) {
const messages = data.messages;
let arr: Message[] = [];
for (const msg of messages) {
if (msg.createdAt > joinTime) {
arr.push({
content: msg.content,
createdAt: msg.createdAt,
id: msg.senderId + msg.createdAt,
senderId: msg.senderId,
});
}
}
setChats(arr);
}
rtdb.ref('/chats/' + roomId).on('value', (snapshot) => {
let arr: Message[] = [];
snapshot.forEach((child) => {
const msg = child.val();
arr.push({
content: msg.content,
createdAt: msg.createdAt,
id: msg.senderId + msg.createdAt,
senderId: msg.senderId,
});
});
setChats(arr);
});
return () => {
chatUnsubscribe();
rtdb.ref('/chats/' + roomId).off('value');
};
}, [roomId, joinTime]);
@ -142,22 +133,24 @@ const Messages: React.FC<MessagesProps> = ({ ownerId, roomId, userId, userList }
return name;
};
const renderMessages = () => {
return allMessages
.sort((msg1, msg2) => msg1.createdAt - msg2.createdAt)
.map((msg) => {
return (
<IonRow key={msg.id} class={msg.senderId === userId ? 'right-align' : ''}>
<IonCol size="auto" class={msg.senderId === userId ? 'my-msg' : 'other-msg'}>
{getName(msg.senderId) !== '' ? <b>{getName(msg.senderId)}: </b> : <></>}
<span>{msg.content}</span>
</IonCol>
</IonRow>
);
});
};
return (
<IonContent class="message-card" ref={contentRef}>
<IonGrid class="message-grid">
{allMessages
.sort((msg1, msg2) => msg1.createdAt - msg2.createdAt)
.map((msg) => {
return (
<IonRow key={msg.id} class={msg.senderId === userId ? 'right-align' : ''}>
<IonCol size="auto" class={msg.senderId === userId ? 'my-msg' : 'other-msg'}>
{getName(msg.senderId) !== '' ? <b>{getName(msg.senderId)}: </b> : <></>}
<span>{msg.content}</span>
</IonCol>
</IonRow>
);
})}
</IonGrid>
<IonGrid class="message-grid">{userList.size === 0 ? <span>Loading...</span> : renderMessages()}</IonGrid>
</IonContent>
);
};

@ -20,9 +20,6 @@ const Home: React.FC = () => {
requests: [],
state: { time: 0, isPlaying: false },
});
await db.collection('chats').doc(roomId.id).set({
messages: [],
});
await db.collection('playlists').doc(roomId.id).set({
createdAt: timestamp,
url: 'https://www.youtube.com/watch?v=XEfDYMngJeE',
@ -35,6 +32,7 @@ const Home: React.FC = () => {
// RealTimeDB preparations
await rtdb.ref('/rooms/' + roomId.id).set({ userCount: 0 });
await rtdb.ref('/available/' + roomId.id).set({ name: 'Room Name', createdAt: new Date().toISOString() });
await rtdb.ref('/chats/' + roomId.id).set({ content: 'created a room.', createdAt: Date.now(), senderId: userId });
const path = '/room/' + roomId.id;
return history.push(path);

@ -114,10 +114,11 @@ const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
// Handle disconnect events
useEffect(() => {
if (!loading && userId !== '' && validRoom) {
const depopulateRoom = async () => {
const depopulate = async () => {
const refUser = rtdb.ref('/rooms/' + roomId + '/' + userId);
const refRoom = rtdb.ref('/rooms/' + roomId);
const refAvailable = rtdb.ref('/available/' + roomId);
const refChat = rtdb.ref('/chats/' + roomId);
// Always remove user from room on disconnect
await refRoom.onDisconnect().update({ userCount: decrement });
@ -127,15 +128,17 @@ const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
if (userCount <= 1) {
await refRoom.onDisconnect().remove();
await refAvailable.onDisconnect().remove();
await refChat.onDisconnect().remove();
} else {
await refRoom.onDisconnect().cancel(); // Cancels all disconnect actions at and under refRoom
await refRoom.onDisconnect().cancel(); // Cancel all disconnect actions
await refAvailable.onDisconnect().cancel();
await refChat.onDisconnect().cancel();
await refRoom.onDisconnect().update({ userCount: decrement }); // User disconnect still needs to be handled
await refUser.onDisconnect().remove();
}
};
depopulateRoom();
depopulate();
}
}, [userId, validRoom, roomId, loading, userCount]);

Loading…
Cancel
Save