From 5cdf300651e59ceb285bcbc508d63c8a8473fca9 Mon Sep 17 00:00:00 2001 From: Simon Huang Date: Wed, 4 Nov 2020 11:38:33 -0500 Subject: [PATCH] moved requests from Firestore to Realtime DB --- schema.ts | 20 ++++++----- src/components/Messages.tsx | 42 +++++++++------------- src/components/Player/ReactPlayerFrame.tsx | 38 +++++++------------- src/components/RoomHeader.tsx | 10 ++---- src/components/Settings.tsx | 19 ++++------ src/pages/Home.tsx | 4 +-- 6 files changed, 50 insertions(+), 83 deletions(-) diff --git a/schema.ts b/schema.ts index 5fb1ab8..13d61c5 100644 --- a/schema.ts +++ b/schema.ts @@ -21,14 +21,6 @@ const collection = { roomId: { createdAt: 'timestamp', ownerId: 'userId', - requests: [ - { - createdAt: 'timestamp', - data: '01:25:44', // Contents of data depend on type of request - type: 'updateState', - senderId: 'userId', - }, - ], }, }, ], @@ -69,6 +61,18 @@ const turtle = { }, }, + // Keeping state requests in Realtime DB could also lower cost + requests: { + roomId: { + requestId: { + createdAt: '2020-10-31T00:12:14.234Z', + data: '01:25:44', // Contents of data depend on type of request + type: 'updateState', + senderId: 'userId', + }, + }, + }, + // Keeping track of which users are present in a room rooms: { roomId: { diff --git a/src/components/Messages.tsx b/src/components/Messages.tsx index 1aa3b3f..5fc9e98 100644 --- a/src/components/Messages.tsx +++ b/src/components/Messages.tsx @@ -1,7 +1,7 @@ import { IonCol, IonContent, IonFabButton, IonGrid, IonIcon, IonInput, IonRow, IonToolbar } from '@ionic/react'; import { sendOutline } from 'ionicons/icons'; import React, { useEffect, useRef, useState } from 'react'; -import { db, rtdb } from '../services/firebase'; +import { rtdb } from '../services/firebase'; import { secondsToTimestamp } from '../services/utilities'; import './Messages.css'; @@ -56,32 +56,24 @@ const Messages: React.FC = ({ pane, ownerId, roomId, userId, user // Listen for new system messages useEffect(() => { - const roomUnsubscribe = db - .collection('rooms') - .doc(roomId) - .onSnapshot((docSnapshot) => { - const docData = docSnapshot.data(); - if (docData !== undefined) { - const requests = docData.requests; - - let arr: Message[] = []; - for (const req of requests) { - if (req.createdAt > joinTime && req.type !== 'updateState') { - arr.push({ - content: processType(req.type, req.data), - createdAt: req.createdAt, - id: req.senderId + req.createdAt, - senderId: req.senderId, - type: req.type, - }); - } - } - setSystemMessages(arr); - } - }); + let arr: Message[] = []; + rtdb.ref('/requests/' + roomId).on('child_added', (snapshot) => { + const req = snapshot.val(); + if (req.createdAt > joinTime && req.type !== 'updateState') { + arr.push({ + content: processType(req.type, req.data), + createdAt: req.createdAt, + id: req.senderId + req.createdAt, + senderId: req.senderId, + type: req.type, + }); + let copyArr = [...arr]; + setSystemMessages(copyArr); + } + }); return () => { - roomUnsubscribe(); + rtdb.ref('/requests/' + roomId).off('child_added'); }; }, [roomId, joinTime]); diff --git a/src/components/Player/ReactPlayerFrame.tsx b/src/components/Player/ReactPlayerFrame.tsx index fcbd769..c54adc2 100644 --- a/src/components/Player/ReactPlayerFrame.tsx +++ b/src/components/Player/ReactPlayerFrame.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import ReactPlayer from 'react-player'; -import { arrayUnion, db } from '../../services/firebase'; +import { db, rtdb } from '../../services/firebase'; import { SYNC_MARGIN } from '../../services/utilities'; type ReactPlayerFrameProps = { @@ -25,11 +25,7 @@ const ReactPlayerFrame: React.FC = ({ ownerId, userId, ro time: currTime, }); - db.collection('rooms') - .doc(roomId) - .update({ - requests: arrayUnion({ createdAt: Date.now(), senderId: userId, data: currTime, type: 'play' }), - }); + rtdb.ref('/requests/' + roomId).push({ createdAt: Date.now(), senderId: userId, data: currTime, type: 'play' }); } } }; @@ -45,11 +41,9 @@ const ReactPlayerFrame: React.FC = ({ ownerId, userId, ro time: currTime, }); - db.collection('rooms') - .doc(roomId) - .update({ - requests: arrayUnion({ createdAt: Date.now(), senderId: userId, data: currTime, type: 'pause' }), - }); + rtdb + .ref('/requests/' + roomId) + .push({ createdAt: Date.now(), senderId: userId, data: currTime, type: 'pause' }); } } }; @@ -57,14 +51,12 @@ const ReactPlayerFrame: React.FC = ({ ownerId, userId, ro // Listen for requests from Firebase (owner only) useEffect(() => { if (ownerId === userId) { - const roomRef = db.collection('rooms').doc(roomId); const stateRef = db.collection('states').doc(roomId); + const requestRef = rtdb.ref('/requests/' + roomId); // Add a listener to 'rooms' collection, listening for updateState requests - const roomUnsubscribe = roomRef.onSnapshot((docSnapshot) => { - const requests = docSnapshot.data()?.requests; - const req = requests[requests.length - 1]; - + requestRef.limitToLast(1).on('child_added', (snapshot) => { + const req = snapshot.val(); if (!!req && req.type === 'updateState' && req.senderId !== userId) { const currTime = player.current?.getCurrentTime(); if (currTime !== undefined) { @@ -77,7 +69,7 @@ const ReactPlayerFrame: React.FC = ({ ownerId, userId, ro }); return () => { - roomUnsubscribe(); + requestRef.limitToLast(1).off('child_added'); }; } }, [ownerId, roomId, userId]); @@ -85,11 +77,7 @@ const ReactPlayerFrame: React.FC = ({ ownerId, userId, ro // Request an update after buffering is finished (member only) const onBufferEnd = () => { if (ownerId !== userId) { - db.collection('rooms') - .doc(roomId) - .update({ - requests: arrayUnion({ createdAt: Date.now(), senderId: userId, data: 0, type: 'updateState' }), - }); + rtdb.ref('/requests/' + roomId).push({ createdAt: Date.now(), senderId: userId, data: 0, type: 'updateState' }); } }; @@ -97,7 +85,7 @@ const ReactPlayerFrame: React.FC = ({ ownerId, userId, ro useEffect(() => { if (ownerId !== userId) { const stateRef = db.collection('states').doc(roomId); - const roomRef = db.collection('rooms').doc(roomId); + const requestRef = rtdb.ref('/requests/' + roomId); let allowUpdate = true; // listen to 'states' collection for video state changes from owner @@ -118,9 +106,7 @@ const ReactPlayerFrame: React.FC = ({ ownerId, userId, ro }, 5000); player.current?.seekTo(realTimeState); - roomRef.update({ - requests: arrayUnion({ createdAt: Date.now(), senderId: userId, data: 0, type: 'updateState' }), - }); + requestRef.push({ createdAt: Date.now(), senderId: userId, data: 0, type: 'updateState' }); } } }); diff --git a/src/components/RoomHeader.tsx b/src/components/RoomHeader.tsx index 76e8493..cd2051d 100644 --- a/src/components/RoomHeader.tsx +++ b/src/components/RoomHeader.tsx @@ -2,7 +2,7 @@ import { IonFabButton, IonIcon, IonInput, IonTitle, IonToolbar } from '@ionic/re import { add } from 'ionicons/icons'; import React, { useState } from 'react'; import { useHistory } from 'react-router'; -import { db, arrayUnion } from '../services/firebase'; +import { db, rtdb } from '../services/firebase'; import './RoomHeader.css'; type RoomHeaderProps = { @@ -21,13 +21,7 @@ const RoomHeader: React.FC = ({ roomId, userId, ownerId }) => { url: videoUrl, }); - await db - .collection('rooms') - .doc(roomId) - .update({ - requests: arrayUnion({ createdAt: Date.now(), senderId: userId, data: 0, type: 'change' }), - }); - + await rtdb.ref('/requests/' + roomId).push({ createdAt: Date.now(), senderId: userId, data: 0, type: 'change' }); setVideoUrl(''); } }; diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 6cfd969..ea258c9 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -17,7 +17,7 @@ import { import { logoGithub } from 'ionicons/icons'; import React, { useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; -import { arrayUnion, db, rtdb } from '../services/firebase'; +import { db, rtdb } from '../services/firebase'; import './Settings.css'; type SettingsProps = { @@ -42,16 +42,9 @@ const Settings: React.FC = ({ pane, roomId, userId }) => { rtdb.ref('/rooms/' + roomId + '/' + userId).set({ name: newName }); // Send 'nameChange' request for all clients to get a message about the name change - db.collection('rooms') - .doc(roomId) - .update({ - requests: arrayUnion({ - createdAt: Date.now(), - senderId: userId, - data: { prev: prevName, curr: newName }, - type: 'nameChange', - }), - }); + rtdb + .ref('/requests/' + roomId) + .push({ createdAt: Date.now(), senderId: userId, data: { prev: prevName, curr: newName }, type: 'nameChange' }); setShowNameChange(true); } @@ -103,12 +96,12 @@ const Settings: React.FC = ({ pane, roomId, userId }) => { - + - + diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index cfd33c2..315851e 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -52,8 +52,6 @@ const Home: React.FC = () => { const roomId = await db.collection('rooms').add({ createdAt: timestamp, ownerId: userId, - requests: [], - state: { time: 0, isPlaying: false }, }); await db.collection('playlists').doc(roomId.id).set({ createdAt: timestamp, @@ -112,7 +110,7 @@ const Home: React.FC = () => { - + Request more options