Supabase单例模式
·
Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.
这个警告表示你在同一个浏览器上下文(同一个标签页或窗口)中创建了多个 GoTrueClient 实例(Supabase 的认证客户端),并且它们使用了相同的存储键(storage key)。
问题原因
- 多个实例共存:你的代码可能多次初始化了
GoTrueClient或 Supabase 客户端,导致多个实例同时运行。 - 共享存储冲突:这些实例会尝试读写相同的浏览器存储(如
localStorage),可能导致认证状态不一致或竞争条件。 - 潜在问题:虽然不会直接报错,但可能导致登录状态异常、Token 失效或并发操作冲突。
如何解决?
1. 确保单例模式(推荐)
在应用中,只初始化一次 Supabase 客户端,后续直接复用该实例。
错误示例 ❌
// 错误:多次创建客户端
const supabase1 = createClient(SUPABASE_URL, SUPABASE_KEY);
const supabase2 = createClient(SUPABASE_URL, SUPABASE_KEY);
正确做法 ✅
// 正确:全局只初始化一次
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
// 其他地方直接使用这个实例
const { data, error } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'password',
});
2. 检查代码是否重复初始化
- 如果你在 React/Vue/Svelte 等框架中,确保客户端实例在应用顶层初始化(如
App.js或全局状态管理)。 - 避免在组件内重复创建 Supabase 客户端。
React 示例(使用 Context 或单例)
// 1. 创建全局 Supabase 实例(如 `lib/supabase.js`)
import { createClient } from '@supabase/supabase-js';
export const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
// 2. 在组件中直接导入使用
import { supabase } from '../lib/supabase';
3. 检查浏览器存储冲突
如果多个标签页或子域名共享相同的 localStorage,可以尝试:
- 使用不同的
storageKey初始化客户端(适用于特殊场景):const supabase = createClient(SUPABASE_URL, SUPABASE_KEY, { auth: { storageKey: 'my_custom_key', // 避免与其他实例冲突 }, });
总结
- 根本原因:多个 GoTrueClient 实例共享同一个浏览器存储。
- 解决方案:确保 Supabase 客户端全局单例,避免重复初始化。
- 适用场景:前端应用(React/Vue/Svelte)、Next.js、Nuxt.js 等。
如果问题仍然存在,请检查是否有第三方插件或脚本意外创建了额外的 Supabase 实例。
更多推荐
所有评论(0)