diff --git a/app/(auth)/signup.js b/app/(auth)/signup.js
index 44315057..df9ce866 100644
--- a/app/(auth)/signup.js
+++ b/app/(auth)/signup.js
@@ -1,5 +1,9 @@
import { Link, useLocalSearchParams } from "expo-router";
-import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
+import {
+ createUserWithEmailAndPassword,
+ sendEmailVerification,
+ updateProfile,
+} from "firebase/auth";
import { doc, setDoc } from "firebase/firestore";
import { useState } from "react";
import {
@@ -32,7 +36,7 @@ export default function SignUp() {
const [password, setPassword] = useState("");
const [passwordCheck, setPasswordCheck] = useState("");
- const { showDialog } = useAlertContext();
+ const { showDialog, showSnackBar } = useAlertContext();
const { height } = useWindowDimensions();
@@ -66,6 +70,15 @@ export default function SignUp() {
uniqueDrills: [],
});
+ try {
+ await sendEmailVerification(auth.currentUser);
+ console.log("Verification Email Sent!");
+ showSnackBar("Verification Email Sent!");
+ } catch {
+ console.log("Error sending verification email: ", e);
+ showDialog("Error", getErrorString(e));
+ }
+
setCurrentUserId(userCredential.user.uid);
setCurrentUserInfo(userCredential.user);
diff --git a/app/content/profile/index.js b/app/content/profile/index.js
index ac86b739..0dfc2737 100644
--- a/app/content/profile/index.js
+++ b/app/content/profile/index.js
@@ -175,7 +175,7 @@ function Index() {
newPassword,
newPasswordCheck,
passwordInputVisible,
- userData.name,
+ userData,
userEmail,
],
);
diff --git a/app/segments/(team)/chooseTeam.js b/app/segments/(team)/chooseTeam.js
index 246ef913..0448e3f1 100644
--- a/app/segments/(team)/chooseTeam.js
+++ b/app/segments/(team)/chooseTeam.js
@@ -1,15 +1,18 @@
import { useQueryClient } from "@tanstack/react-query";
import { router } from "expo-router";
-import { signOut as signoutFireBase } from "firebase/auth";
+import {
+ onIdTokenChanged,
+ sendEmailVerification,
+ signOut as signoutFireBase,
+} from "firebase/auth";
import { doc, getDoc, setDoc } from "firebase/firestore";
-import { useEffect, useState } from "react";
-import { Text, View } from "react-native";
+import { useCallback, useEffect, useState } from "react";
+import { RefreshControl, ScrollView, Text, View } from "react-native";
import { Button } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
import { themeColors } from "~/Constants";
import { getErrorString } from "~/Utility";
import ErrorComponent from "~/components/errorComponent";
-import Loading from "~/components/loading";
import { useAlertContext } from "~/context/Alert";
import { useAuthContext } from "~/context/Auth";
import { invalidateMultipleKeys } from "~/dbOperations/invalidateMultipleKeys";
@@ -20,13 +23,15 @@ function ChooseTeam() {
useAuthContext();
const queryClient = useQueryClient();
- const { showDialog } = useAlertContext();
+ const { showDialog, showSnackBar } = useAlertContext();
const [blacklist, setBlacklist] = useState(false);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ const [verified, setVerified] = useState(false);
+
async function handleSignOut() {
try {
await signoutFireBase(auth);
@@ -58,9 +63,41 @@ function ChooseTeam() {
}
}, [currentUserId]);
- if (loading) {
- return ;
- }
+ useEffect(() => {
+ const unregisterAuthObserver = onIdTokenChanged(auth, async (user) => {
+ if (user) {
+ if (user.emailVerified) {
+ setVerified(true);
+ showSnackBar("Email successfully verified.");
+ clearInterval(intervalId); // Stop the interval when email is verified
+ unregisterAuthObserver(); // Unregister the auth observer
+ } else {
+ setVerified(false);
+ console.log("Error: Email Not Verified Yet, Try Again");
+ }
+ }
+ });
+
+ // Set up an interval to check email verification every 10 seconds
+ const intervalId = setInterval(async () => {
+ if (auth.currentUser) {
+ await auth.currentUser.reload();
+ }
+ }, 10000); // 10,000 ms = 10 seconds
+
+ return () => {
+ clearInterval(intervalId); // Clean up the interval when component unmounts
+ unregisterAuthObserver(); // Unregister the auth observer
+ };
+ }, []);
+
+ const [refreshing, setRefreshing] = useState(false);
+
+ const onRefresh = useCallback(async () => {
+ setRefreshing(true);
+ await auth.currentUser.reload();
+ setRefreshing(false);
+ }, []);
if (error) {
return ;
@@ -73,38 +110,35 @@ function ChooseTeam() {
justifyContent: "center",
}}
>
-
+ }
+ contentContainerStyle={{ flex: 1, justifyContent: "center" }}
>
- {blacklist ? (
-
- You've been banned from this team.
-
- ) : (
-
+
+ {blacklist ? (
+
+ You've been banned from this team.
+
+ ) : verified ? (
-
- )}
-
+ ) : (
+
+ Waiting for email verification...
+
+
+ )}
-
+
);
}
diff --git a/context/Auth.js b/context/Auth.js
index aabf79e3..e73d4f4f 100644
--- a/context/Auth.js
+++ b/context/Auth.js
@@ -1,5 +1,5 @@
import { useRouter, useSegments } from "expo-router";
-import { onAuthStateChanged } from "firebase/auth";
+import { onIdTokenChanged } from "firebase/auth";
import { createContext, useContext, useEffect, useState } from "react";
import { auth } from "~/firebaseConfig";
@@ -11,6 +11,7 @@ const AuthContext = createContext({
currentUserId: null,
currentTeamId: null,
currentUserInfo: null,
+ currentUserVerified: false,
});
export function useAuthContext() {
@@ -35,12 +36,13 @@ export const AuthProvider = ({ children }) => {
const [currentUserId, setCurrentUserId] = useState(null);
const [currentUserInfo, setCurrentUserInfo] = useState(null);
const [currentTeamId, setCurrentTeamId] = useState("1");
+ const [currentUserVerified, setCurrentUserVerified] = useState(false);
useProtectedRoute(currentUserId);
useEffect(() => {
//if this code is not in here, it'll run for infinite times
- onAuthStateChanged(auth, (newlyLoggedInUser) => {
+ onIdTokenChanged(auth, (newlyLoggedInUser) => {
// test user login (yarn test)
// If you sign out, reload or click "sign in" to login as test user
// Signout functionality for test user is buggy, chance of auto-logging back in
@@ -55,10 +57,13 @@ export const AuthProvider = ({ children }) => {
setCurrentUserId(newlyLoggedInUser["uid"] ?? "Error (uid)");
setCurrentUserInfo(newlyLoggedInUser ?? {});
console.log("user changed. userId:", newlyLoggedInUser["uid"]);
+ if (auth.currentUser.emailVerified) {
+ setCurrentUserVerified(true);
+ }
}
}
});
- }, []);
+ }, [currentUserVerified]);
return (
{
setCurrentUserInfo(userInfo);
},
currentUserInfo,
+ currentUserVerified,
}}
>
{children}
diff --git a/dbOperations/hooks/useUserInfo.js b/dbOperations/hooks/useUserInfo.js
index 6efd0d2d..a6f9c96c 100644
--- a/dbOperations/hooks/useUserInfo.js
+++ b/dbOperations/hooks/useUserInfo.js
@@ -17,7 +17,8 @@ export const useUserInfo = ({
role = null,
enabled = true,
} = {}) => {
- const { currentTeamId, currentUserId } = useAuthContext();
+ const { currentTeamId, currentUserId, currentUserVerified } =
+ useAuthContext();
const week_milliseconds = 604800000;
const currentDate = new Date();
const currentDateTime = currentDate.getTime();
@@ -31,7 +32,8 @@ export const useUserInfo = ({
doc(db, "teams", currentTeamId, "users", userId),
);
const data = querySnapshot.data();
- if (!data) {
+
+ if (!data || !currentUserVerified) {
if (currentUserId === userId) {
router.replace("segments/(team)/chooseTeam");
}