feat: google auth poc

This commit is contained in:
2024-11-01 14:17:50 +01:00
parent d2a4e74713
commit 569f81d9b9
7 changed files with 116 additions and 32 deletions

3
.gitignore vendored
View File

@@ -77,4 +77,5 @@ expo-env.d.ts
# erm
*google-services.json
keys.txt
keys.txt
android/

View File

@@ -27,7 +27,8 @@
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "dev.srizan.featheroom"
"package": "dev.srizan.featheroom",
"googleServicesFile": "./lib/google-services.json"
},
"web": {
"bundler": "metro",

View File

@@ -1,17 +1,28 @@
import { Stack } from 'expo-router'
import { View } from 'react-native'
import { Button, Text } from 'react-native-paper'
import { StackHeader } from '@/lib/ui'
import { useAuth } from '@/lib/providers/auth'
const Layout = () => (
<Stack
screenOptions={{
animation: 'slide_from_bottom',
header: (props) => <StackHeader navProps={props} children={undefined} />,
}}
>
<Stack.Screen name="login" options={{ title: 'Log in' }} />
<Stack.Screen name="signup" options={{ title: 'Sign up' }} />
</Stack>
)
function Layout() {
const { signIn, user } = useAuth()
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button onPress={async () => await signIn()}>log in!</Button>
<Text>this is {JSON.stringify(user)}.</Text>
</View>
/* <Stack
screenOptions={{
animation: 'slide_from_bottom',
header: (props) => (
<StackHeader navProps={props} children={undefined} />
),
}}
>
<Stack.Screen name="login" options={{ title: 'Log in' }} />
<Stack.Screen name="signup" options={{ title: 'Sign up' }} />
</Stack> */
)
}
export default Layout

View File

@@ -12,6 +12,7 @@ import { PaperProvider } from 'react-native-paper'
import { Setting } from '@/lib/types'
import { StackHeader, Themes } from '@/lib/ui'
import { AuthProvider } from '@/lib/providers/auth'
export {
// Catch any errors thrown by the Layout component.
@@ -85,23 +86,25 @@ const RootLayoutNav = () => {
][settings.color]
}
>
<Stack
screenOptions={{
animation: 'slide_from_bottom',
header: (props) => (
<StackHeader navProps={props} children={undefined} />
),
}}
>
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="drawer" options={{ headerShown: false }} />
<Stack.Screen name="search" options={{ title: 'Search' }} />
<Stack.Screen
name="modal"
options={{ title: 'Modal', presentation: 'modal' }}
/>
</Stack>
<AuthProvider>
<Stack
screenOptions={{
animation: 'slide_from_bottom',
header: (props) => (
<StackHeader navProps={props} children={undefined} />
),
}}
>
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="drawer" options={{ headerShown: false }} />
<Stack.Screen name="search" options={{ title: 'Search' }} />
<Stack.Screen
name="modal"
options={{ title: 'Modal', presentation: 'modal' }}
/>
</Stack>
</AuthProvider>
</PaperProvider>
)
}

BIN
bun.lockb

Binary file not shown.

67
lib/providers/auth.tsx Normal file
View File

@@ -0,0 +1,67 @@
import {
GoogleSignin,
type User,
} from '@react-native-google-signin/google-signin'
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'
interface AuthProviderProps {
children: ReactNode
}
export function AuthProvider({ children }: AuthProviderProps) {
const [user, setUser] = useState<User | null>(null)
GoogleSignin.configure({
scopes: [
'https://www.googleapis.com/auth/classroom.courses.readonly',
'https://www.googleapis.com/auth/classroom.coursework.me',
'https://www.googleapis.com/auth/classroom.coursework.students',
'https://www.googleapis.com/auth/classroom.coursework.students.readonly',
'https://www.googleapis.com/auth/classroom.coursework.me.readonly',
],
})
useEffect(() => {
setUser(GoogleSignin.getCurrentUser())
}, [])
const signIn = async () => {
try {
await GoogleSignin.hasPlayServices()
const userInfo = await GoogleSignin.signIn()
setUser(userInfo.data)
return userInfo
} catch (error) {
console.error(error)
}
}
const signOut = async () => {
try {
await GoogleSignin.signOut()
setUser(null)
} catch (error) {
console.error(error)
}
}
return (
<AuthContext.Provider value={{ user, signIn, signOut }}>
{children}
</AuthContext.Provider>
)
}
interface AuthContextType {
user: User | null
signIn: () => Promise<any>
signOut: () => Promise<void>
}
const AuthContext = createContext<AuthContextType>({
user: null,
signIn: async () => null,
signOut: async () => {},
})
export const useAuth = (): AuthContextType => useContext(AuthContext)

View File

@@ -21,6 +21,7 @@
"@expo-google-fonts/jetbrains-mono": "^0.2.3",
"@expo-google-fonts/noto-sans": "^0.2.3",
"@expo/vector-icons": "^14.0.0",
"@react-native-google-signin/google-signin": "^13.1.0",
"@react-navigation/drawer": "^6.6.15",
"@react-navigation/native": "^6.0.2",
"@shopify/flash-list": "1.6.4",