Проблема в том, что после выбора пользователя и принятия согласия на экране, когда redirectBack возвращает токен ответа Google, AuthContext, который управляет аутентификацией, похоже, настроен неправильно. Я считаю, что перенаправление приводит к перезагрузке представления, и ответ обрабатывается неправильно.
Почему я думаю, что проблема связана с AuthContext?
Потому что, если Я перемещаю всю логику входа в основной файл _layout.tsx и удаляю AuthContext, он работает и правильно возвращает токен.
Любопытно то, что вход в систему работает правильно... (с моим сервером), я думаю, это может быть связано с перенаправлением Google
Это структура каталогов моего приложения:

Хорошо, это приложение/_layout.tsx (точка входа)
function RootLayoutNavigation() {
const tamaguiConfig = createTamagui(config);
return (
);
}
Для управления аутентификацией у меня создан контекст (который, как я подозреваю, неправильно настроен и может быть источником проблемы)
AuthContext.tsx
import React, {useContext, createContext, type PropsWithChildren, useEffect, useState} from 'react';
import {loadUser, login, logout} from "~/services/AuthService";
import {useRouter, useSegments} from "expo-router";
import {getToken} from "~/services/TokenService";
import {ActivityIndicator} from "react-native";
import {View} from "tamagui";
type User = any;
interface AuthContextType {
user: User | null;
signIn: (userData: User) => void;
signOut: () => Promise;
isLoading: boolean;
isAuthenticated: boolean;
}
const AuthContext = createContext({
user: null,
signIn: () => {},
signOut: async () => {},
isLoading: true,
isAuthenticated: false,
});
function useProtectedRoute(user: User | null) {
const segments = useSegments();
const router = useRouter();
console.log("segments", segments)
useEffect(() => {
if (segments.length === 0) return;
const inAuthGroup = segments[0] === '(auth)';
if (!user && !inAuthGroup) {
console.log("entra 1")
router.replace('/(auth)/login');
} else if (user && inAuthGroup) {
console.log("entra 2")
router.replace('/(drawer)');
}
}, [user, segments]);
}
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [isAuthenticated, setIsAuthenticated] = useState(false);
useProtectedRoute(user);
useEffect(() => {
async function loadSession() {
try {
const token = await getToken();
if (token) {
const userData = await loadUser();
setUser(userData);
setIsAuthenticated(true);
}
} catch (error) {
console.error('Error loading session:', error);
} finally {
setIsLoading(false);
}
}
loadSession();
}, []);
const signIn = (userData: User) => {
setUser(userData);
setIsAuthenticated(true);
};
const signOut = async () => {
try {
await logout();
setUser(null);
setIsAuthenticated(false);
} catch (error) {
console.error('Error during logout:', error);
}
};
return (
{!isLoading ? children : (
)}
);
}
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}
И страница входа в систему login.tsx
const Login = () => {
const { signIn } = useAuth();
const router = useRouter()
const [isLoadingLogin, setIsLoadingLogin] = useState(false)
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [errors, setErrors] = useState({})
const config = {
androidClientId: "client-id",
webClientId: "client-id 2",
expoClientId: "client-id 3"
}
const [request, response, promptAsync] = Google.useAuthRequest(config);
React.useEffect(() => {
handleEffect()
}, [response])
async function handleEffect(){
// Here is always null.
console.warn("handle Effect() - token " + response)
}
return (
Log-in
{JSON.stringify(response)} // Also there is always null.{
setEmail(text);
}}
keyboardType="email-address"
autoCapitalize="none"
/>
promptAsync()}
style={({ pressed }) => ({
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
padding: 10,
borderRadius: 30,
backgroundColor: pressed ? '#f0f0f0' : '#ffffff',
borderWidth: 1,
borderColor: '#dcdcdc',
})}
>
Entrar con Google
)
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... irect-back
Мобильная версия