You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C Firebase账户删除遇FIRAuthErrorCodeRequiresRecentLogin问题求助

问题描述

我的应用因未提供账户删除功能被App Store拒绝,应用支持Sign in with Apple、Google及邮箱登录。按照Firebase文档执行账户删除操作时,收到错误FIRAuthErrorCodeRequiresRecentLogin,提示:

Delete account error This operation is sensitive and requires recent authentication. Log in again before retrying this request.

当前执行删除的代码如下:

FIRUser* user = [ [ FIRAuth auth ] currentUser ];

[ user deleteWithCompletion:^(NSError * _Nullable error) {
    
    if( error )
    {
        // An error happened.
        if( error.code == FIRAuthErrorCodeRequiresRecentLogin)
        {
             return;
        }
     }
  }

我知道需要重新认证后才能删除账户,目前的做法是让用户登出再登录后执行删除,但用户体验很差。想请教如何获取已通过Google、Apple或邮箱登录用户的FIRAuthCredential,以完成重新认证并删除账户?

目前的重新认证代码片段(待补充Credential获取逻辑):

// How to get a credential when I am already signed in via google, apple, or email?
FIRAuthCredential* credential;

NSLog( @"Delete account error %@", error.localizedDescription );

[[FIRAuth auth].currentUser reauthenticateWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
    
    NSLog( @"Error %@", error);
}];
解决方案

针对不同登录方式,获取FIRAuthCredential的实现逻辑不同,以下是分场景的具体方案:

1. 邮箱密码登录用户

需要让用户重新输入密码,通过邮箱和密码生成EmailAuthCredential:

// 从当前用户获取邮箱,再通过弹窗获取用户重新输入的密码
NSString *email = [[FIRAuth auth].currentUser email];
NSString *password = @"用户输入的密码";

FIRAuthCredential *credential = [FIREmailAuthProvider credentialWithEmail:email password:password];

2. Google登录用户

借助Google Sign-In SDK,从已登录的Google用户实例中提取认证信息,转换为GoogleAuthCredential:

// 获取当前已登录的Google用户实例
GIDGoogleUser *googleUser = [GIDSignIn sharedInstance].currentUser;
if (googleUser) {
    GIDAuthentication *authentication = googleUser.authentication;
    FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken accessToken:authentication.accessToken];
}

注:需确保项目已正确集成Google Sign-In SDK,且用户未主动登出Google账号。

3. Sign in with Apple登录用户

通过Apple的AuthenticationServices框架发起重新授权请求,用返回的身份令牌生成OAuthCredential:

// 初始化Apple授权请求
ASAuthorizationAppleIDProvider *provider = [[ASAuthorizationAppleIDProvider alloc] init];
NSString *userID = [[FIRAuth auth].currentUser providerData.firstObject uid]; // 获取用户绑定的Apple ID

[provider createRequestWithUserID:userID completion:^(ASAuthorizationAppleIDRequest * _Nullable request, NSError * _Nullable error) {
    if (!error) {
        request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
        ASAuthorizationController *controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        controller.delegate = self;
        controller.presentationContextProvider = self;
        [controller performRequests];
    }
}];

// 实现Apple授权回调,获取Credential并执行重新认证+删除
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization {
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
        NSString *identityToken = [[NSString alloc] initWithData:appleIDCredential.identityToken encoding:NSUTF8StringEncoding];
        NSString *authorizationCode = [[NSString alloc] initWithData:appleIDCredential.authorizationCode encoding:NSUTF8StringEncoding];
        
        FIRAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com" IDToken:identityToken accessToken:authorizationCode];
        
        // 重新认证后删除账户
        [[FIRAuth auth].currentUser reauthenticateWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
            if (!error) {
                [[FIRAuth auth].currentUser deleteWithCompletion:^(NSError * _Nullable error) {
                    if (!error) {
                        // 删除成功,处理后续逻辑
                    }
                }];
            }
        }];
    }
}

// 提供Apple授权弹窗的展示上下文
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller {
    return self.view.window;
}

完整流程示例

整合上述逻辑,完整的删除账户处理流程如下:

// 触发账户删除
- (void)triggerAccountDelete {
    FIRUser *user = [FIRAuth auth].currentUser;
    [user deleteWithCompletion:^(NSError * _Nullable error) {
        if (error) {
            if (error.code == FIRAuthErrorCodeRequiresRecentLogin) {
                [self reauthenticateAndDelete];
            }
        } else {
            // 删除成功逻辑
        }
    }];
}

// 根据登录方式获取Credential并重新认证
- (void)reauthenticateAndDelete {
    FIRUser *user = [FIRAuth auth].currentUser;
    NSString *providerID = user.providerData.firstObject.providerID;
    
    if ([providerID isEqualToString:@"password"]) {
        // 邮箱密码登录:弹窗获取密码
        NSString *password = @"用户输入的密码";
        FIRAuthCredential *credential = [FIREmailAuthProvider credentialWithEmail:user.email password:password];
        [self finishReauthenticateAndDelete:credential];
    } else if ([providerID isEqualToString:@"google.com"]) {
        // Google登录:获取当前Google用户
        GIDGoogleUser *googleUser = [GIDSignIn sharedInstance].currentUser;
        if (googleUser) {
            GIDAuthentication *auth = googleUser.authentication;
            FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:auth.idToken accessToken:auth.accessToken];
            [self finishReauthenticateAndDelete:credential];
        } else {
            // Google用户已登出,需引导重新登录
        }
    } else if ([providerID isEqualToString:@"apple.com"]) {
        // Apple登录:发起重新授权请求(代码同上述Apple场景)
        ASAuthorizationAppleIDProvider *provider = [[ASAuthorizationAppleIDProvider alloc] init];
        NSString *userID = user.providerData.firstObject.uid;
        [provider createRequestWithUserID:userID completion:^(ASAuthorizationAppleIDRequest * _Nullable request, NSError * _Nullable error) {
            if (!error) {
                request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
                ASAuthorizationController *controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
                controller.delegate = self;
                controller.presentationContextProvider = self;
                [controller performRequests];
            }
        }];
    }
}

// 执行重新认证并删除账户
- (void)finishReauthenticateAndDelete:(FIRAuthCredential *)credential {
    [[FIRAuth auth].currentUser reauthenticateWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
        if (!error) {
            [[FIRAuth auth].currentUser deleteWithCompletion:^(NSError * _Nullable error) {
                if (!error) {
                    // 删除成功后的逻辑(如跳转登录页)
                } else {
                    // 删除失败处理
                }
            }];
        } else {
            // 重新认证失败处理(如提示用户重新操作)
        }
    }];
}

内容的提问来源于stack exchange,提问作者Jafar Mohammed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:09:31