如何删除通过自定义令牌创建的FirebaseAuth当前登录用户
问题根因
无报错但自定义Token登录用户未删除的核心原因和Firebase Auth的自定义Token身份验证逻辑有关:
- 自定义Token生成的用户会话,删除账户这类敏感操作要求的「最近登录」校验规则和标准OAuth提供商逻辑一致,你当前的重认证逻辑存在缺陷:如果
signInWithLine操作完成后,依然是通过云函数换取自定义Token再调用signInWithCustomToken完成登录,这个操作在Firebase Auth的校验逻辑中不属于有效重认证,会被判定为会话时效不符合要求,而你代码中第二次调用删除方法时没有捕获异常,所以看不到具体报错。 - 另外一种常见场景是客户端本地缓存的用户信息已经过期,调用
currentUser.delete时请求没有携带有效身份凭证,Firebase后端静默拒绝了请求但客户端SDK没有抛出明确异常。
修复步骤
1. 补全二次删除操作的异常捕获
先给重认证后的删除操作补全异常捕获,确认具体报错代码:
Future<void> deleteAccount() async { try { await FirebaseAuth.instance.currentUser?.delete(); } on FirebaseAuthException catch (e, s) { if (e.code == 'requires-recent-login') { print('The user must reauthenticate before this operation can be executed.'); await signInWithLine(); // 补全这部分的异常捕获 try { await FirebaseAuth.instance.currentUser?.delete(); } on FirebaseAuthException catch (e2, s2) { print('二次删除报错:\n$e2'); print('栈信息:\n$s2'); } } else { print('Firebase auth delete account error:\n$e'); print('============stack=========\n$s'); } } catch (e, s) { print('Firebase auth delete account error:\n$e'); print('============stack=========\n$s'); } }
2. 使用指定方法完成自定义Token用户重认证
如果确认报错依然是requires-recent-login,说明signInWithCustomToken不算有效重认证,需要改用reauthenticateWithCustomToken方法完成重认证,不要直接走全量登录流程:
final user = FirebaseAuth.instance.currentUser; // 从云函数拿到最新的自定义Token final newCustomToken = await 你的云函数换Token方法(新的LINE令牌); // 执行重认证 await user?.reauthenticateWithCustomToken(newCustomToken); // 重认证完成后再调用删除 await user?.delete();
3. 兜底方案:后端云函数执行删除
如果客户端侧始终无法成功删除,可以把删除逻辑迁移到云函数侧,客户端调用云函数传递当前用户的ID Token,云函数校验Token有效性后调用Admin SDK的deleteUser方法直接删除用户,这个方式不受客户端登录会话限制,成功率更高。
云函数示例(Node.js):
exports.deleteUser = functions.https.onCall(async (data, context) => { if (!context.auth) { throw new functions.https.HttpsError('unauthenticated', '用户未登录'); } try { await admin.auth().deleteUser(context.auth.uid); return { success: true }; } catch (e) { throw new functions.https.HttpsError('internal', '删除失败'); } });
客户端调用代码:
final res = await FirebaseFunctions.instance.httpsCallable('deleteUser').call(); if (res.data['success']) { // 删除成功,执行登出、跳转登录页等逻辑 }
内容的提问来源于stack exchange,提问作者Tristan Bennett
相关产品推荐
相关产品推荐

