- Implemented connecting multiple accounts for google

This commit is contained in:
Dejan
2024-10-20 18:34:48 +02:00
parent 80cc184498
commit bb72c6c011
4 changed files with 90 additions and 51 deletions

View File

@ -90,8 +90,11 @@ const CalendarSettingsPage = (props: {
const userInfo = await userInfoResponse.json(); const userInfo = await userInfoResponse.json();
const googleMail = userInfo.email; const googleMail = userInfo.email;
let googleAccounts = profileData?.googleAccounts;
const updatedGoogleAccounts = googleAccounts ? {...googleAccounts, [googleMail]: accessToken} : {[googleMail]: accessToken};
await updateUserData({ await updateUserData({
newUserData: {googleToken: accessToken, googleMail: googleMail}, newUserData: {googleAccounts: updatedGoogleAccounts},
}); });
await fetchAndSaveGoogleEvents({token: accessToken, email: googleMail}) await fetchAndSaveGoogleEvents({token: accessToken, email: googleMail})
@ -263,11 +266,14 @@ const CalendarSettingsPage = (props: {
debouncedUpdateUserData(color); debouncedUpdateUserData(color);
}; };
const clearToken = async (provider: "google" | "outlook" | "apple") => { const clearToken = async (provider: "google" | "outlook" | "apple", email: string) => {
const newUserData: Partial<UserProfile> = {}; const newUserData: Partial<UserProfile> = {};
if (provider === "google") { if (provider === "google") {
newUserData.googleToken = null; let googleAccounts = profileData?.googleAccounts;
newUserData.googleMail = null; if (googleAccounts) {
googleAccounts[email] = null;
newUserData.googleAccounts = googleAccounts;
}
} else if (provider === "outlook") { } else if (provider === "outlook") {
newUserData.microsoftToken = null; newUserData.microsoftToken = null;
newUserData.outlookMail = null; newUserData.outlookMail = null;
@ -278,6 +284,16 @@ const CalendarSettingsPage = (props: {
await updateUserData({newUserData}); await updateUserData({newUserData});
}; };
let isConnectedToGoogle = false;
if (profileData?.googleAccounts) {
Object.values(profileData?.googleAccounts).forEach((item) => {
if (item !== null) {
isConnectedToGoogle = true;
return;
}
});
}
return ( return (
<ScrollView> <ScrollView>
<View marginH-30 marginB-30> <View marginH-30 marginB-30>
@ -378,8 +394,8 @@ const CalendarSettingsPage = (props: {
</Text> </Text>
<Button <Button
onPress={() => !profileData?.googleToken ? promptAsync() : clearToken("google")} onPress={() => promptAsync()}
label={profileData?.googleToken ? `Disconnect ${profileData.googleMail}` : "Connect Google"} label={"Connect Google"}
labelStyle={styles.addCalLbl} labelStyle={styles.addCalLbl}
labelProps={{ labelProps={{
numberOfLines: 2 numberOfLines: 2
@ -393,8 +409,29 @@ const CalendarSettingsPage = (props: {
color="black" color="black"
text70BL text70BL
/> />
{profileData?.googleAccounts ? Object.keys(profileData?.googleAccounts)?.map((googleMail) => {
const googleToken = profileData?.googleAccounts?.[googleMail];
return googleToken && <Button
key={googleMail}
onPress={() => clearToken("google", googleMail)}
label={`Disconnect ${googleMail}`}
labelStyle={styles.addCalLbl}
labelProps={{
numberOfLines: 2
}}
iconSource={() => (
<View marginR-15>
<GoogleIcon/>
</View>
)}
style={styles.addCalBtn}
color="black"
text70BL
/>
}) : null}
<Button <Button
onPress={() => !profileData?.appleToken ? handleAppleSignIn() : clearToken("google")} onPress={() => !profileData?.appleToken ? handleAppleSignIn() : clearToken("apple")}
label={profileData?.appleToken ? `Disconnect ${profileData.appleMail}` : "Connect Apple"} label={profileData?.appleToken ? `Disconnect ${profileData.appleMail}` : "Connect Apple"}
labelStyle={styles.addCalLbl} labelStyle={styles.addCalLbl}
labelProps={{ labelProps={{
@ -426,7 +463,7 @@ const CalendarSettingsPage = (props: {
text70BL text70BL
/> />
{(profileData?.googleMail || profileData?.outlookMail || profileData?.appleMail) && ( {(isConnectedToGoogle || profileData?.outlookMail || profileData?.appleMail) && (
<> <>
<Text style={styles.subTitle} marginT-30 marginB-20> <Text style={styles.subTitle} marginT-30 marginB-20>
Connected Calendars Connected Calendars
@ -434,21 +471,17 @@ const CalendarSettingsPage = (props: {
<View style={styles.noPaddingCard}> <View style={styles.noPaddingCard}>
<View style={{marginTop: 20}}> <View style={{marginTop: 20}}>
{!!profileData?.googleMail && ( {Object.keys(profileData?.googleAccounts)?.map((googleEmail) => {
const googleToken = profileData?.googleAccounts?.[googleEmail];
return googleToken && (
<TouchableOpacity <TouchableOpacity
onPress={() => fetchAndSaveGoogleEvents({ onPress={() => fetchAndSaveGoogleEvents({token: googleToken, email: googleEmail})}
token: profileData?.googleToken!,
email: profileData?.googleMail!
})}
> >
<View row paddingR-20 center> <View row paddingR-20 center>
<Button <Button
disabled={isSyncingGoogle} disabled={isSyncingGoogle}
onPress={() => fetchAndSaveGoogleEvents({ onPress={() => fetchAndSaveGoogleEvents({token: googleToken, email: googleEmail})}
token: profileData?.googleToken!, label={`Sync ${googleEmail}`}
email: profileData?.googleMail!
})}
label={`Sync ${profileData?.googleMail}`}
labelStyle={styles.addCalLbl} labelStyle={styles.addCalLbl}
labelProps={{numberOfLines: 3}} labelProps={{numberOfLines: 3}}
iconSource={() => ( iconSource={() => (
@ -468,7 +501,8 @@ const CalendarSettingsPage = (props: {
)} )}
</View> </View>
</TouchableOpacity> </TouchableOpacity>
)} )
})}
{!!profileData?.appleMail && ( {!!profileData?.appleMail && (

View File

@ -188,11 +188,17 @@ exports.refreshTokens = functions.pubsub.schedule('every 12 hours').onRun(async
profilesSnapshot.forEach(async (profileDoc) => { profilesSnapshot.forEach(async (profileDoc) => {
const profileData = profileDoc.data(); const profileData = profileDoc.data();
if (profileData.googleToken) { if (profileData.googleAccounts) {
try { try {
const refreshedGoogleToken = await refreshGoogleToken(profileData.googleToken); for (const googleEmail of Object.keys(profileData?.googleAccounts)) {
await profileDoc.ref.update({googleToken: refreshedGoogleToken}); const googleToken = profileData?.googleAccounts?.[googleEmail];
if (googleToken) {
const refreshedGoogleToken = await refreshGoogleToken(googleToken);
const updatedGoogleAccounts = {...profileData.googleAccounts, [googleEmail]: refreshedGoogleToken};
await profileDoc.ref.update({googleAccounts: updatedGoogleAccounts});
console.log(`Google token updated for user ${profileDoc.id}`); console.log(`Google token updated for user ${profileDoc.id}`);
}
}
} catch (error) { } catch (error) {
console.error(`Error refreshing Google token for user ${profileDoc.id}:`, error.message); console.error(`Error refreshing Google token for user ${profileDoc.id}:`, error.message);
} }

View File

@ -18,15 +18,14 @@ export interface UserProfile {
familyId?: string; familyId?: string;
uid?: string; uid?: string;
pfp?: string; pfp?: string;
googleToken?: string | null;
microsoftToken?: string | null; microsoftToken?: string | null;
appleToken?: string | null; appleToken?: string | null;
eventColor?: string | null; eventColor?: string | null;
googleMail?: string | null;
outlookMail?: string | null; outlookMail?: string | null;
appleMail?: string | null; appleMail?: string | null;
timeZone?: string | null; timeZone?: string | null;
firstDayOfWeek?: string | null; firstDayOfWeek?: string | null;
googleAccounts?: Object;
} }
export interface ParentProfile extends UserProfile { export interface ParentProfile extends UserProfile {

View File

@ -14,12 +14,12 @@ export const useFetchAndSaveGoogleEvents = () => {
const timeMin = new Date(new Date().setFullYear(new Date().getFullYear() - 1)); const timeMin = new Date(new Date().setFullYear(new Date().getFullYear() - 1));
const timeMax = new Date(new Date().setFullYear(new Date().getFullYear() + 5)); const timeMax = new Date(new Date().setFullYear(new Date().getFullYear() + 5));
console.log("Token: ", token ?? profileData?.googleToken); console.log("Token: ", token);
try { try {
const response = await fetchGoogleCalendarEvents( const response = await fetchGoogleCalendarEvents(
token ?? profileData?.googleToken, token,
email ?? profileData?.googleMail, email,
profileData?.familyId, profileData?.familyId,
timeMin.toISOString().slice(0, -5) + "Z", timeMin.toISOString().slice(0, -5) + "Z",
timeMax.toISOString().slice(0, -5) + "Z" timeMax.toISOString().slice(0, -5) + "Z"