maintain user presence in rooms with Realtime Database

pull/3/head
Simon Huang 5 years ago
parent ace5e1157d
commit a326c7dc87

@ -1,7 +1,7 @@
import { IonButton, IonContent, IonGrid, IonHeader, IonPage, IonRow, IonTitle, IonToolbar } from '@ionic/react'; import { IonButton, IonContent, IonGrid, IonHeader, IonPage, IonRow, IonTitle, IonToolbar } from '@ionic/react';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';
import { db, timestamp } from '../services/firebase'; import { db, timestamp, auth, rtdb } from '../services/firebase';
import './Home.css'; import './Home.css';
const Home: React.FC = () => { const Home: React.FC = () => {
@ -10,20 +10,32 @@ const Home: React.FC = () => {
let history = useHistory(); let history = useHistory();
const handleClick = async () => { // Populate both Firestore and RealTimeDB before navigating to room
const createRoom = async () => {
const roomId = await db.collection('rooms').add({ const roomId = await db.collection('rooms').add({
createdAt: timestamp, createdAt: timestamp,
ownerId: userId, ownerId: userId,
}); });
await rtdb.ref('/rooms/' + roomId.id).set({ [userId]: 'placeholder', exists: true });
const path = '/room/' + roomId.id; const path = '/room/' + roomId.id;
return history.push(path); return history.push(path);
}; };
// Sign in anonymously before showing Create Room button
useEffect(() => { useEffect(() => {
console.log('Hook fired'); const authUnsubscribe = auth.onAuthStateChanged((user) => {
setUserId('placeholder'); if (user) {
setLoading(false); setUserId(user.uid);
setLoading(false);
} else {
auth.signInAnonymously();
}
});
return () => {
authUnsubscribe();
};
}, []); }, []);
return ( return (
@ -39,7 +51,7 @@ const Home: React.FC = () => {
{loading ? ( {loading ? (
<IonContent className="ion-padding">Loading...</IonContent> <IonContent className="ion-padding">Loading...</IonContent>
) : ( ) : (
<IonButton onClick={handleClick}>Create Room</IonButton> <IonButton onClick={createRoom}>Create Room</IonButton>
)} )}
</IonRow> </IonRow>
</IonGrid> </IonGrid>

@ -1,13 +1,14 @@
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react'; import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { RouteComponentProps, useHistory } from 'react-router'; import { RouteComponentProps, useHistory } from 'react-router';
import { db } from '../services/firebase'; import { auth, db, rtdb } from '../services/firebase';
const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => { const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
const history = useHistory(); const history = useHistory();
const roomId = match.params.roomId; const roomId = match.params.roomId;
const [loading, setLoading] = useState(true); const [validRoom, setValidRoom] = useState(false);
const [userId, setUserId] = useState('');
// Verify that the roomId exists in db // Verify that the roomId exists in db
useEffect(() => { useEffect(() => {
@ -16,14 +17,50 @@ const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
if (!room.exists) { if (!room.exists) {
history.push('/'); history.push('/');
} else { } else {
setLoading(false); setValidRoom(true);
} }
}; };
console.log('Hook fired');
fetchRoom(); fetchRoom();
}, [history, roomId]); }, [history, roomId]);
// Handle logging in
useEffect(() => {
const authUnsubscribe = auth.onAuthStateChanged((user) => {
if (user) {
setUserId(user.uid);
} else {
auth.signInAnonymously();
}
});
return () => {
authUnsubscribe();
};
}, []);
// Keep track of user presence in realtime database rooms
useEffect(() => {
if (userId !== '' && validRoom) {
const populateRoom = async () => {
// Keep userId in the room as long as a connection from the client exists
rtdb.ref('/rooms/' + roomId).on('value', async (snapshot) => {
if (snapshot.val()) {
await rtdb.ref('/rooms/' + roomId).update({ [userId]: 'placeholder' });
}
});
// Remove userId from the room on disconnect (closing a browser window/tab)
await rtdb
.ref('/rooms/' + roomId + '/' + userId)
.onDisconnect()
.remove();
};
populateRoom();
}
}, [userId, validRoom, roomId]);
return ( return (
<IonPage> <IonPage>
<IonHeader> <IonHeader>
@ -31,7 +68,7 @@ const Room: React.FC<RouteComponentProps<{ roomId: string }>> = ({ match }) => {
<IonTitle>Turtle</IonTitle> <IonTitle>Turtle</IonTitle>
</IonToolbar> </IonToolbar>
</IonHeader> </IonHeader>
{!loading ? ( {validRoom ? (
<IonContent className="ion-padding">Video and chat</IonContent> <IonContent className="ion-padding">Video and chat</IonContent>
) : ( ) : (
<IonContent className="ion-padding">Loading...</IonContent> <IonContent className="ion-padding">Loading...</IonContent>

Loading…
Cancel
Save