Почему не работает вход Apple с FirebaseUI?

#ios #swift #firebase #firebase-authentication #firebaseui

# #iOS #swift #firebase #firebase-аутентификация #firebaseui

Вопрос:

Следуя приведенному здесь руководству, я пытаюсь добавить вход Apple в свое приложение для iOS. Я успешно внедрил вход в Google с помощью этого метода, но Apple, похоже, не работает. Я могу дойти до того, что он запрашивает мой пароль 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. Я запускаю это на симуляторе, нужно ли запускать его с реального устройства?

Обновить

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

Я попытался заменить каждый из сертификатов / ключей и восстановить новые безрезультатно

Именно здесь я был остановлен в процессе входа: Вот часть входа, на которой застревает мое приложение

Обновление 4

Похоже, что ошибка, отмеченная выше, не возникает после входа в систему, но не связана. При входе в систему я не получаю никаких ошибок. Я не понимаю, почему authUI() функция не запускается.

Ответ №1:

Дом Я использовал вход в Apple в приложении, но он находится в Objective-c. Поток очень прост для тестирования даже в Objective-C, если вы не используете.

В представлении с логином я добавил это предложение для делегирования.

 @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:@"x", 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, amp;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 resu<
}

- (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 с помощью FireBase
Но если вы будете следовать им, это должно работать на физическом устройстве, в симуляторе нетривиально заставить его работать.

Комментарии:

1. Спасибо, я решил свою проблему, но по какой-то причине они удалили мой ответ, так что поехали.

2. Неудачно. Мне действительно не помешал бы ответ на этот вопрос. Конечно, я мог бы использовать приведенный выше ответ и самостоятельно настроить Apple login, но весь смысл FirebaseUI в том, чтобы иметь чистую библиотеку, которая позаботится об этом за нас. вы случайно не помните, что вы сделали, чтобы это исправить?

Ответ №2:

вы должны добавить права входа в Apple в свой идентификатор пакета приложений из учетной записи разработчика Apple, а из учетной записи разработчика Apple вы должны загрузить ключ и загрузить этот ключ в firebase, после чего ваш вход в Apple начнет работать. Очень часто создается ключ, найденный при первом поиске из Google очень легко

Комментарии:

1. и для меня это также работает на симуляторе, но для лучшего тестирования попробуйте его на физическом устройстве

2. Привет, Сакиб, и спасибо за ваш ответ. Я уже добавил права входа и загрузил ключ к своему проекту firebase.

3. разрешили ли вы загрузку атрибутов из info.plist? <ключ>NSAppTransportSecurity</ключ> <dict> <ключ> NSAllowsArbitraryLoads</ключ> <true/> </dict>

4. или, возможно, вам придется вызывать его в dispatch DispatchQueue.main.async { }

5. Я добавил это и до сих пор получаю тот же результат

Ответ №3:

используйте этот пример, я надеюсь, он сработает для вас

         let authUI = FUIAuth.defaultAuthUI()
        authUI?.shouldHideCancelButton = true
        authUI?.delegate = delegate
        authUI?.tosurl = Constants.Url.kFirebaseTermsOfService
        authUI?.privacyPolicyURL = Constants.Url.kFirebasePrivacyPolicy
        
        let emailAuth = FUIEmailAuth()
        let facebookAuth = FUIFacebookAuth(permissions: ["public_profile", "email"])
        let googleAuth = FUIGoogleAuth()
        
        var providers: [FUIAuthProvider] = [emailAuth, facebookAuth, googleAuth]
        if useAnonymous {
            let anonymousAuth = FUIAnonymousAuth()
            providers.append(anonymousAuth)
        }

        if #available(iOS 13.0, *) {
            let appleAuth = FUIOAuth.appleAuthProvider()
            providers.append(appleAuth)
        }

        authUI?.providers = providers