ios - 为什么使用 FirebaseUI 的苹果登录不起作用?

标签 ios swift firebase firebase-authentication firebaseui

按照 here 指南,我正在尝试将 Apple 登录添加到我的 iOS 应用程序。我已经使用这种方法成功实现了谷歌登录,但 Apple 似乎无法正常工作。我可以到达它要求我的苹果密码的地步,但它只是继续加载而没有结果,我收到以下错误:

2020-12-10 13:19:38.020129-0500 Pikit[5268:114225] Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
2020-12-10 13:19:38.121991-0500 Pikit[5268:114225] Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service

需要说明的是,这些错误出现在我选择与该应用程序共享我的电子邮件之后和实际输入密码之前。如果我输入的密码不正确,它会通知我,但如果我输入的密码正确,它就不会继续。它不会挂起,它根本不会继续,没有任何解释。

这是触发登录流程的代码:

@IBAction func loginPressed(_ sender: UIButton) {
        
        let authUI = FUIAuth.defaultAuthUI()
        guard authUI != nil else {
           return
        }
        authUI?.providers = [
            FUIEmailAuth(),
            FUIGoogleAuth(),
            FUIOAuth.appleAuthProvider()
        ]
        authUI?.delegate = self
        let authViewController = authUI!.authViewController()
        authViewController.modalPresentationStyle = .overCurrentContext
        self.present(authViewController, animated: true, completion: nil)
        
    }
    
//This function is not being triggered
    func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) {
        if let user = authDataResult?.user{
            print("Nice! You've signed in as \(user.uid)")
            performSegue(withIdentifier: K.welcomeSegue, sender: self)
        }
        print(error!)
    }

我还确保我的 Firebase 项目已启用 Apple,Apple 登录在我的权利中,并且我已上传我的 iOS 授权 key 。我在模拟器上运行它,是否需要在真实设备上运行?

更新

authUI 函数根本没有运行,因为我尝试在条件之外插入打印语句,但没有收到任何输出。为什么这不会运行?

错误似乎是在我调用 present() 方法之后发生的。

更新 2

完整的控制台输出:

2020-12-11 13:53:55.697034-0500 Pikit[4563:85919] Task <9849E252-C9AF-4F35-88A7-1946BD0B4270>.<2> finished with error [-1003] Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_kCFStreamErrorCodeKey=8, NSUnderlyingError=0x6000006edec0 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_kCFStreamErrorCodeKey=8, _kCFStreamErrorDomainKey=12}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <9849E252-C9AF-4F35-88A7-1946BD0B4270>.<2>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <9849E252-C9AF-4F35-88A7-1946BD0B4270>.<2>"
), NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLStringKey=https://firebasedynamiclinks-ipv6.googleapis.com/v1/installAttribution?key=AIzaSyDAKtfpyKw0QG5Db9jtdHYQfAOgI-FASWE, NSErrorFailingURLKey=https://firebasedynamiclinks-ipv6.googleapis.com/v1/installAttribution?key=AIzaSyDAKtfpyKw0QG5Db9jtdHYQfAOgI-FASWE, _kCFStreamErrorDomainKey=12}
2020-12-11 13:53:55.733365-0500 Pikit[4563:85634] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=3 "Target is not running or required target entitlement is missing" UserInfo={RBSAssertionAttribute=<RBSDomainAttribute| domain:"com.apple.webkit" name:"Background" sourceEnvironment:"(null)">, NSLocalizedFailureReason=Target is not running or required target entitlement is missing}>
2020-12-11 13:53:55.733582-0500 Pikit[4563:85634] [ProcessSuspension] 0x1098fed80 - ProcessAssertion: Failed to acquire RBS Background assertion 'WebProcess Background Assertion' for process with PID 4565, error: Error Domain=RBSAssertionErrorDomain Code=3 "Target is not running or required target entitlement is missing" UserInfo={RBSAssertionAttribute=<RBSDomainAttribute| domain:"com.apple.webkit" name:"Background" sourceEnvironment:"(null)">, NSLocalizedFailureReason=Target is not running or required target entitlement is missing}
2020-12-11 13:53:55.977723-0500 Pikit[4563:85800] 6.25.0 - [Firebase/Messaging][I-FCM012002] Error in application:didFailToRegisterForRemoteNotificationsWithError: remote notifications are not supported in the simulator
2020-12-11 13:53:56.045387-0500 Pikit[4563:85800] 6.25.0 - [Firebase/Analytics][I-ACS800023] No pending snapshot to activate. SDK name: app_measurement
2020-12-11 13:53:56.227368-0500 Pikit[4563:85800] 6.25.0 - [Firebase/Analytics][I-ACS800023] No pending snapshot to activate. SDK name: app_measurement
2020-12-11 13:53:56.282593-0500 Pikit[4563:85800] 6.25.0 - [Firebase/Analytics][I-ACS023012] Analytics collection enabled
2020-12-11 13:53:56.355765-0500 Pikit[4563:85824] 6.25.0 - [Firebase/Analytics][I-ACS023001] Deep Link does not contain valid required params. URL params: {
    dismiss = 1;
    "is_weak_match" = 1;
}
2020-12-11 13:54:25.474653-0500 Pikit[4563:85634] Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
2020-12-11 13:54:25.749707-0500 Pikit[4563:85634] Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service

我尝试了多种不同的方法并多次阅读文档,但仍然看不出我做错了什么。

更新 3

我已经尝试替换每个证书/ key 并重新生成新的,但没有效果

这是我在登录流程中被阻止的地方: Here is the part of sign-in that my app gets stuck on

更新 4

上面提到的错误似乎不是在登录后发生的,而是无关的。登录时我没有收到任何错误。我不明白为什么没有触发 authUI() 函数。

最佳答案

House 我在应用程序中使用了 Apple Signin,但它是在 Objective-c 中。如果您不使用该流程,即使在 Objective-C 中也很容易测试。

在带有登录的 View 中,我为委托(delegate)添加了这句话。

@import Firebase;
@import GoogleSignIn;

@interface loginViewController () <GIDSignInDelegate, ASAuthorizationControllerDelegate>

然后在点击按钮后,我执行 AppleSignIn ASAuthorizationControllerDelegate 流程,如下所示:

- (IBAction)startSignInWithAppleFlow:(id)sender
{
    if (@available(iOS 13.0, *)) {
        NSString *nonce = [self randomNonce:32];
        self.currentNonce = nonce;
        ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
        ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest];
        request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
        request.nonce = [self stringBySha256HashingString:nonce];

        ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        authorizationController.delegate = self;
        authorizationController.presentationContextProvider = self;
        [authorizationController performRequests];
    }
}

- (NSString *)stringBySha256HashingString:(NSString *)input
{
    const char *string = [input UTF8String];
    unsigned char result[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(string, (CC_LONG)strlen(string), result);

    NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
    for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [hashed appendFormat:@"%02x", result[i]];
    }
    return hashed;
}

- (NSString *)randomNonce:(NSInteger)length
{
    NSAssert(length > 0, @"Expected nonce to have positive length");
    NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
    NSMutableString *result = [NSMutableString string];
    NSInteger remainingLength = length;

    while (remainingLength > 0) {
        NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16];
        for (NSInteger i = 0; i < 16; i++) {
            uint8_t random = 0;
            int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random);
            NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode);

            [randoms addObject:@(random)];
        }

        for (NSNumber *random in randoms) {
            if (remainingLength == 0) {
                break;
            }

            if (random.unsignedIntValue < characterSet.length) {
                unichar character = [characterSet characterAtIndex:random.unsignedIntValue];
                [result appendFormat:@"%C", character];
                remainingLength--;
            }
        }
    }
    
    return result;
}

- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0))
{
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
        NSString *rawNonce = self.currentNonce;
        NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent.");

        if (appleIDCredential.identityToken == nil) {
            NSLog(@"Unable to fetch identity token.");
            return;
        }

        NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken encoding:NSUTF8StringEncoding];
        if (idToken == nil) {
            NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken);
        }

        // Initialize a Firebase credential.
        FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com"
                                                                            IDToken:idToken
                                                                           rawNonce:rawNonce];

        // Sign in with Firebase.
        [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
            if (error != nil) {
                // Error. If error.code == FIRAuthErrorCodeMissingOrInvalidNonce,
                // make sure you're sending the SHA256-hashed nonce as a hex string
                // with your request to Apple.
                
                NSLog(@"%ld - %@ - %@", error.code, error.description, error.localizedDescription);
                
                return;
            }
            // Sign-in succeeded!
            // User successfully signed in. Get user data from the FIRUser object
            if (authResult == nil) { return; }
            FIRUser *user = authResult.user;
            // ...
            NSLog(@"%@", user);
            
            // ...
            [[NSNotificationCenter defaultCenter] postNotificationName:@"LOGIN_SUCCESSFUL" object:nil];
            [self dismissViewControllerAnimated:YES completion:nil];
        }];
    }
}

- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0))
{
    NSLog(@"Sign in with Apple errored: %@", error);
}

不知道大家有没有按照这个链接的注意事项:Apple Sign In with FireBase 但是如果你按照他们的要求去做,它应该可以在物理设备上工作,在模拟器中让它工作并不是微不足道的。

关于ios - 为什么使用 FirebaseUI 的苹果登录不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65240217/

相关文章:

ios - 如何修复不一致的颜色到清晰的径向渐变层

ios - 如何使用变异函数设置类属性?

android - 应用程序打开时未收到 Firebase Messaging Android 通知

ios - 无法阻止 Sprite 移出屏幕

ios - 如何弱链接 iOS 应用程序委托(delegate)方法?

ios - 如何从 IOS 应用程序打开特定的 Facebook 帖子。不是 Facebook 页面。打开 Facebook 帖子的正确 url 方案?

ios - 登录工作线程

swift - TimeZone 当前不起作用

firebase - 如何在不花钱的情况下检查 firestore 中是否存在具有给定 id 的文档?

java - 无法将 java.lang.String 类型的对象转换为 com.mycare.OtherClass 类型