Skip to content

Android — Firebase Authentication Core / 原生登录 UI ​

选择模块与依赖 ​

模块Maven 坐标用途
auth-firebasecom.ronpad.sdk:ro-auth-firebase:0.1.0Firebase App/Auth、Session、ID Token、匿名登录、Provider 凭证、link/reauth、账号观察与登出
auth-firebase-uicom.ronpad.sdk:ro-auth-firebase-ui:0.1.0可选原生登录模态、已关联 Provider 身份卡、缓存倒计时、重试/换方式、四语言

Core 使用 Firebase Auth 22.1.2,最低 Android 23;UI 只依赖 Core,不强制安装 Google/Apple/Facebook 授权模块或 Egret。请在项目配置实际可用的 ROSDK 私有 Maven 仓库,并使用已固定、能从仓库下载的版本:

groovy
// 使用应用实际可访问的 ROSDK 私有 Maven 源。
implementation 'com.ronpad.sdk:ro-auth-firebase:0.1.0'
// 需要 ROSDK 统一原生登录窗口时再引入:
implementation 'com.ronpad.sdk:ro-auth-firebase-ui:0.1.0'

宿主初始化与 Firebase Session ​

java
// 宿主已安全配置并初始化 FirebaseApp(或使用显式 FirebaseOptions)。
ROAuthFirebase core = ROAuthFirebase.forDefaultApp();
// Firebase currentUser/hasSession 不代表 Token 有效或游戏已登录。
core.getIdToken(false, new ROAuthFirebase.Completion() {
    @Override public void onSuccess(ROAuthFirebase.Session session) {
        // 将 session.idToken 经 HTTPS 给游戏服务器验签/兑换 account/token;不打印 ID Token。
    }
    @Override public void onFailure(String code, Exception error) {
        // 可重试 Token 获取、网络失败或失效会话;只输出安全错误码。
    }
});

Core 还支持 initialize(context, FirebaseOptions, appName)、signInAnonymously、signInWithCredential、linkWithCredential、reauthenticate、getIdToken(forceRefresh)、observe 和 signOut(OperationCallback);本地退出必须通过回调把成功或异常返回给宿主。Google Credential Manager 的 Google ID Token 可由 ROAuthFirebase.googleCredential(idToken) 构造 Firebase 凭证;Google ID Token 与 Firebase ID Token 不同。Apple 在 Android 使用 Firebase 官方 OAuth 凭证入口;不要把游戏后端 Apple 一次性 code 当作 Firebase Credential。

可选 UI:匿名登录示例 ​

java
ROFirebaseLoginUI.Options options = new ROFirebaseLoginUI.Options();
options.loginMethods = ROFirebaseLoginUI.ANONYMOUS;
options.showCachedAccount = true;
options.allowSwitchAccount = true;
options.autoContinueSeconds = 3; // 默认逐秒 3→2→1,设 0 禁止自动继续。
options.timeoutSeconds = 60;      // 仅 UI 等待超时,不代表取消官方网络请求。

ROFirebaseLoginUI ui = new ROFirebaseLoginUI(activity, core, options);
ui.show(new ROFirebaseLoginUI.Completion() {
    @Override public void onSuccess(ROAuthFirebase.Session session) {
        // 只代表 Firebase 身份成功;宿主仍需通过游戏服务器验签与兑换。
    }
    @Override public void onCancel() {
        // 只允许宿主生命周期主动结束;不能视为已登录游戏。
    }
    @Override public void onFailure(String code, Exception error) {
        // 非终态、可恢复失败;UI 保留重试/选择其他方式,不直接放行游戏。
    }
});
// Activity 销毁时 ui.dismiss(),不在用户必需登录面板上提供跳过按钮。

Google/Apple 等需通过 registerProvider / registerSessionProvider 注册真实实现,且 loginMethods 允许才显示;不能因为 Firebase User 的 providerIDs 存在就假设已安装 Provider。Facebook 目前仅支持展示 Firebase 已关联身份,未实现独立 Facebook 登录模块。合规品牌图标由对应 Provider/宿主注入,缺失时用中性图标。缓存身份多 Provider 显示的是已关联方式而不是最近一次登录方式;不显示完整邮箱/UID/Token,不下载远程头像阻塞登录。

SDK 成功与游戏 sdk.login() 成功的边界 ​

text
游戏 sdk.login() → Firebase UI/Session + ID Token
                     ↓
               宿主 Platform : SDKDelegate 调用游戏服务端 auth.Auth
                     ├─ 有效游戏 account/token → 单次向游戏返回成功
                     └─ 拒绝/网络失败/无效账号 → 游戏仍未登录
                            → 宿主可刷新 Token、重试服务器或再次打开 SDK UI

Firebase 的会话可保留以免用户重复授权;游戏认证失败不必自动 Firebase signOut。真正换号涉及未绑定游客进度时,必须让用户确认;不能用 UI 成功直接解锁游戏。Firebase Core/UI 不负责游戏账号认证,也不需要额外的 loginFlush();业务最终状态由原有宿主管理。

宿主需要注意 ​

  • 按需注册可用 Provider Handler,未安装的登录方式不会显示;已有 Firebase providerData 只代表关联身份,不表示可直接授权。
  • 账号缓存、Token 过期、Activity 销毁、网络失败和重复回调都应在现有宿主处理,不记录明文 Token 或完整账号资料。
  • UI 支持 en/zh/th/id 系统语言;具体字符串不跟随 Egret 游戏语言。
  • 当前未提供独立 Facebook 原生登录 Provider;展示 Facebook 关联标记不等于支持 Facebook OAuth 登录。

API 全览:Firebase Auth Core(可不安装 UI) ​

Maven 候选:com.ronpad.sdk:ro-auth-firebase:0.1.0。Core 只管理 Firebase 身份/Token,不包含游戏后端 auth.Auth、游戏 account/token、Egret 协议,也不强制依赖 ROSDK Google/Apple Provider。

公开 Java 接口参数、回调与用途
new ROAuthFirebase(FirebaseApp app)宿主已配置 FirebaseApp 时构造
ROAuthFirebase.forDefaultApp()获取已初始化的默认 Firebase App(缺配置抛错)
ROAuthFirebase.initialize(context, FirebaseOptions, appName)不用 google-services 插件时显式创建/复用指定 Firebase App
currentUser()、hasSession()当前本地身份快照和有无缓存用户,不保证 Token 仍有效
observe(StateListener) → Subscription观察 Firebase 身份,Subscription.remove() 在宿主销毁时解除监听
getIdToken(forceRefresh, Completion)本地会话刷新/获取 Token;forceRefresh=true 强制刷新
signInAnonymously(Completion)Firebase 匿名用户,不等于业务游客登录
signInWithCredential(credential, Completion)使用独立 Provider 返回的 Firebase AuthCredential
linkWithCredential(credential, Completion)将凭证关联到当前 Firebase 账号
reauthenticate(credential, Completion)对当前 Firebase 账号重新认证
googleCredential(googleIdToken)Google ID Token 转为 Firebase AuthCredential(不应传 serverAuthCode)
signInWithApple(activity, Completion)Android Firebase 官方 Apple OAuth
linkWithApple(activity, Completion)、reauthenticateWithApple(activity, Completion)Apple 账号关联/重新认证
signOut(OperationCallback)Firebase 会话登出;不会替宿主注销游戏服务器或 Credential Manager
Completion.onSuccess(Session)、onFailure(code, Exception)Firebase 层最终回调;成功仍需游戏服务器核验
StateListener.onChanged(UserSnapshot)只是身份变化,不意味着游戏登录成功

Session 有 user 和机密 idToken;UserSnapshot 有 uid、displayName、anonymous、providers,providers 只表示已关联的来源。公开错误常量:ERROR_NO_USER、ERROR_INVALID_CREDENTIAL、ERROR_CANCELLED、ERROR_STALE_SESSION、ERROR_FIREBASE;保留处理其他上游错误码的分支。

java
ROAuthFirebase core = ROAuthFirebase.initialize(
    applicationContext, firebaseOptions, "game-auth");
// 如果宿主已配置 default FirebaseApp,亦可用 ROAuthFirebase.forDefaultApp()。
ROAuthFirebase.Subscription subscription = core.observe(user -> {
    // user 可能为 null;不是游戏 sdk.login() 的完成事件
});
ROAuthFirebase.Completion callback = new ROAuthFirebase.Completion() {
    @Override public void onSuccess(ROAuthFirebase.Session session) {
        // 宿主把 session.idToken 通过 HTTPS 交给游戏服务器 auth.Auth 验签和兑换。
    }
    @Override public void onFailure(String code, Exception error) {
        // Firebase 层失败,由宿主决定重试、选择方式等。
    }
};
// 选用所需的 API,无需全部执行:
core.signInAnonymously(callback);
// core.signInWithCredential(firebaseCredential, callback);
// core.linkWithCredential(firebaseCredential, callback);
// core.reauthenticate(firebaseCredential, callback);
// core.signInWithApple(activity, callback);
// core.linkWithApple(activity, callback);
// core.reauthenticateWithApple(activity, callback);
// core.getIdToken(true, callback);
// AuthCredential google = ROAuthFirebase.googleCredential(googleIdToken);
// 观察不用时:subscription.remove();
// 主动退出 Firebase:core.signOut(error -> {
    // error == null 表示 Firebase 本地退出成功;不代表游戏后端退出。
});

API 全览:可选 Firebase 登录 UI ​

UI 候选:com.ronpad.sdk:ro-auth-firebase-ui:0.1.0,只依赖 Core,不会把所有 Google/Apple/Meta 库强制拉进应用。

生命周期建议:应用按需配置并复用 Core;每次宿主 sdk.login() 新的登录流程创建一次 UI 实例,在宿主 Activity 有效期间持有;注册已实际接入的 Provider,调用 show。UI 内部管理缓存账号卡、3→2→1 倒计时、方式列表、授权与 Core 调用、重试、关闭及迟到回调。宿主 Activity 的 onDestroy() 调用 dismiss(),但不应在服务器 auth.Auth 失败时让游戏误以为已登录;此时应在宿主层保持门控、重试服务器或重新开启登录流程。不是每次点击“继续”就 new UI。

UI 公开接口用法
new ROFirebaseLoginUI(activity, core, options)构建一个当前 Activity 所属的模态登录流程
show(Completion)展示一次登录窗口;已经显示时重复 show 拒绝
state()当前流程 State:IDLE、CHOOSING、CACHED_ACCOUNT、AUTHORIZING、FIREBASE_AUTHENTICATING、REFRESHING_TOKEN、SUCCEEDED、FAILED、CANCELLED
registerProvider(method, Provider)注册获取 AuthCredential 的独立第三方授权实现
registerSessionProvider(method, SessionProvider)注册直接调用 Firebase Core 产生 Session 的方式(如 Android Apple OAuth)
unregisterProvider(method)注销授权实现,两种 handler 类型一并移除
setProviderIcon(method, Drawable)注入有许可的品牌图标;未提供时使用中性素材
dismiss()宿主主动销毁窗口时关闭、清理定时与迟到响应,不供玩家跳过必需登录
Completion.onSuccess(Session)只表示 Firebase Session 成功;宿主仍须业务验签
Completion.onFailure(code,error)默认可选的非终态错误通知,SDK 留窗重试
Completion.onCancel()只表示宿主主动终止 UI,不是成功登录
Provider.authorize(Activity,CredentialCallback) / CredentialCallback.complete(credential,error,cancelled)独立 OAuth Provider 异步返回 Firebase 凭证
SessionProvider.authorize(Activity,Mode,ROAuthFirebase.Completion)自行实现 SIGN_IN/LINK/REAUTHENTICATE 的 Firebase 会话路径

Options 全字段:loginMethods(默认 GOOGLE|APPLE,但只显示真实已注册 Handler)、preferredOrder(按钮顺序)、showCachedAccount=true、autoContinueSeconds=3(设 0 关闭)、timeoutSeconds=60(设 0 不超时,超时不取消上游)、allowSwitchAccount=true、showAnonymousWarning=true、accentColor、mode=SIGN_IN。模式枚举为 SIGN_IN / LINK / REAUTHENTICATE。方式位:GOOGLE=1、FACEBOOK=2、GITHUB=4、TWITTER=8、MICROSOFT=16、YAHOO=32、APPLE=64、ANONYMOUS=512;仅位值存在不代表项目已有对应 SDK。

java
ROFirebaseLoginUI.Options options = new ROFirebaseLoginUI.Options();
options.loginMethods = ROFirebaseLoginUI.GOOGLE | ROFirebaseLoginUI.ANONYMOUS;
options.autoContinueSeconds = 3;
options.mode = ROFirebaseLoginUI.Mode.SIGN_IN;
ROFirebaseLoginUI ui = new ROFirebaseLoginUI(activity, core, options);
// 将 ui 作为当前宿主登录流程的成员保存,而非方法局部临时引用。
ui.registerProvider(ROFirebaseLoginUI.GOOGLE, (a, done) ->
    ROLoginGoogle.signIn(a, webClientId, executor,
        new ROLoginGoogle.Completion() {
            @Override public void onSuccess(String token) {
                done.complete(ROAuthFirebase.googleCredential(token), null, false);
            }
            @Override public void onFailure(Exception e, boolean cancelled) {
                done.complete(null, e, cancelled);
            }
        }));
ui.show(new ROFirebaseLoginUI.Completion() {
    @Override public void onSuccess(ROAuthFirebase.Session session) {
        // Firebase 身份成功。游戏服务器 auth.Auth 成功并返回 account/token 后
        // 宿主才按原有 SDKDelegate 协议结束游戏 sdk.login()。
    }
    @Override public void onFailure(String code, Exception error) {
        // 此处非终态,SDK 登录弹窗会保留并提示重试/换方式。
    }
    @Override public void onCancel() {
        // 宿主销毁登录 UI;仍不可把未认证游戏当已登录。
    }
});
// 当前 Activity.onDestroy() 必须调用 ui.dismiss()。

只需匿名的应用可设置 loginMethods=ANONYMOUS,不需要调用 registerProvider;Android Apple 可选用 registerSessionProvider(APPLE, (activity,mode,done) -> ...),按模式调用 Core 的 signInWithApple/linkWithApple/reauthenticateWithApple。没有真实 Provider 的按钮不显示。正式游戏不应出现重复初始化 Firebase 或再次从 UI 直接调用游戏业务 auth.Auth 的实现。

**验收状态:**上述 Core/UI 为已审查的 Draft 公开 API;最新源码构建/真实游戏 OAuth 和生产服务器仍须按仓库 HANDOFF 单独验收。

2026-10-28 登录与退出回调准则 ​

  • ROAuthFirebase.signOut(OperationCallback) 现在必须给出退出回调;同步 Firebase SDK 调用完成后在主线程返回 onComplete(Exception error)。此接口只清除 Firebase 本地会话,游戏业务账号的退出仍需宿主调用自己的服务端。
  • ROFirebaseLoginUI.Completion 的 onSuccess(Session)、onCancel()、onFailure(code,error) 均需实现。UI 内部失败会保留重试/重新选择方式,不能将 onFailure 当成已获得游戏登录结果,更不能放行未认证的游戏会话。
  • 核心和 UI 是两个可选独立模块,登录 UI 持有 Core、自己调用 Firebase 并管理倒计时、窗口和状态;宿主在 Core 返回 Session 后仍须完成游戏服务器 ID Token 验证/账号兑换。

按需接入独立 SDK 模块,按真实宿主配置原生接口。