Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 6x 1x 1x 5x 1x 1x 1x 2x 2x 1x 2x 2x 1x 1x 1x | /**
* Supabase 客户端配置
*/
import AsyncStorage from '@react-native-async-storage/async-storage';
import { createClient } from '@supabase/supabase-js';
import { logger } from '@/src/utils/logger';
// Supabase 配置(从环境变量读取)
const SUPABASE_URL = process.env.EXPO_PUBLIC_SUPABASE_URL || '';
const SUPABASE_ANON_KEY = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY || '';
// 配置验证
Eif (!SUPABASE_URL || !SUPABASE_ANON_KEY) {
console.error('❌ Supabase 配置缺失!');
console.error('请在 .env 文件中添加:');
console.error('EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co');
console.error('EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key');
console.error('然后重启: npm start -- --clear');
}
// URL 格式验证
Iif (SUPABASE_URL && !SUPABASE_URL.startsWith('https://')) {
console.error('❌ SUPABASE_URL 格式错误,应该以 https:// 开头');
}
/** Supabase 客户端实例 */
export const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
auth: {
// 使用 AsyncStorage 持久化 Session
storage: AsyncStorage,
// 自动刷新 Token
autoRefreshToken: true,
// 持久化 Session(应用重启后保持登录)
persistSession: true,
// React Native 不需要检测 URL 中的 Session
detectSessionInUrl: false,
},
// 全局配置
global: {
headers: {
'X-Client-Type': 'pet-love-mobile',
},
},
});
/** 检查 Supabase 是否已正确配置 */
export const isSupabaseConfigured = (): boolean => {
return !!(SUPABASE_URL && SUPABASE_ANON_KEY);
};
/** 获取当前 Session */
export const getSession = async () => {
try {
const { data, error } = await supabase.auth.getSession();
if (error) {
logger.error('获取 Session 失败', error as Error);
return null;
}
return data.session;
} catch (error) {
logger.error('获取 Session 异常', error as Error);
return null;
}
};
/** 检查用户是否已登录 */
export const isAuthenticated = async (): Promise<boolean> => {
const session = await getSession();
return !!session;
};
/** 获取当前用户 ID */
export const getCurrentUserId = async (): Promise<string | null> => {
const session = await getSession();
return session?.user?.id || null;
};
// ==================== 兼容旧代码的导出 ====================
// 注意:以下函数主要用于兼容旧代码,新代码应直接使用 supabaseAuthService
/**
* @deprecated 使用 supabaseAuthService.login() 替代
* 设置 Supabase 认证 Session(兼容旧代码)
*/
export const setSupabaseAuth = async (
accessToken: string,
refreshToken: string
): Promise<boolean> => {
try {
const { error } = await supabase.auth.setSession({
access_token: accessToken,
refresh_token: refreshToken,
});
if (error) {
logger.error('设置 Supabase Session 失败', error as Error);
return false;
}
logger.info('Supabase 认证已同步');
return true;
} catch (error) {
logger.error('设置 Supabase Session 异常', error as Error);
return false;
}
};
/**
* @deprecated 使用 supabaseAuthService.logout() 替代
* 清除 Supabase 认证 Session(兼容旧代码)
*/
export const clearSupabaseAuth = async (): Promise<void> => {
try {
await supabase.auth.signOut();
logger.info('Supabase Session 已清除');
} catch (error) {
logger.error('清除 Supabase Session 失败', error as Error);
}
};
/**
* @deprecated 不再需要手动初始化,Session 会自动从 AsyncStorage 恢复
* 初始化 Supabase 认证(兼容旧代码)
*/
export const initSupabaseAuth = async (): Promise<void> => {
// Session 会自动从 AsyncStorage 恢复,无需手动操作
const session = await getSession();
logger.info('Supabase Session 状态', { isLoggedIn: !!session });
};
export default supabase;
|