skip to Main Content

I have followed the instructions on https://firebase.google.com/docs/auth/ios/twitter-login to a T for Swift and I get the web popup to authorise the App I created on Twitter Dev, the callback is called and then the webview sits on an empty page of about:blank. Nothing can be done but click the Done button which then results in a Error Domain=FIRAuthErrorDomain Code=17058 “The interaction was cancelled by the user.”
Callback address is correct. I’ve used the Twitter Consumer API Keys as the keys to enter in the Firebase console.

What am I missing?

4

Answers


  1. Chosen as BEST ANSWER

    Ok so I resolved this question but not entirely sure how now. I believe it was because the callback wasn't being issued and thus not picked up by the app. The callback wasn't issue due to the authentication and I believe because I hadn't created the terms of service and privacy policy. So make sure you have done that in the Twitter dev page.

    In the twitter dev page, the callback link is: https://yourApp.firebaseapp.com/__/auth/handler You'll find this in your firebase authentication settings when you enable twitter.

    Ensure you have in info.plist LSApplicationQueriesSchemes an array of: twitter twitterauth

    In your swift file:

    var provider = OAuthProvider(providerID: "twitter.com")
    

    Your button action:

    @IBAction func onCustonTwitterButtonPressed(_ sender: Any) {
        MyAppsCoreServicesScripts.logoutSocial() // My logout routine.
        provider.getCredentialWith(nil) { credential, error in
        if let error = error {
            MyAppsCoreServicesScripts.showError(prefix: "Twitter Login",error: error, showMsg: true)
            } else if credential != nil {
                self.firebaseLogin(credential!)            
            }
        }
    }
    

    Good luck! Hope this helps someone.


  2. For everyone who still has an issue with getting callback working, I managed to fix it. Sadly, you have to edit the method in the library (not the best way, but still. Bug was reported to firebase team). The method should look like the one below (you can find it in the file named FIROAuthProvider.m, line 125. I intentionally left commented lines, so you see the problem there… Hope it helps somebody 🙂

    - (void)getCredentialWithUIDelegate:(nullable id<FIRAuthUIDelegate>)UIDelegate
                             completion:(nullable FIRAuthCredentialCallback)completion {
      if (![FIRAuthWebUtils isCallbackSchemeRegisteredForCustomURLScheme:self->_callbackScheme]) {
        [NSException raise:NSInternalInconsistencyException
                    format:@"Please register custom URL scheme '%@' in the app's Info.plist file.",
                           self->_callbackScheme];
      }
    //  __weak __typeof__(self) weakSelf = self;
    //  __weak FIRAuth *weakAuth = _auth;
    //  __weak NSString *weakProviderID = _providerID;
      dispatch_async(FIRAuthGlobalWorkQueue(), ^{
        FIRAuthCredentialCallback callbackOnMainThread =
            ^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
              if (completion) {
                dispatch_async(dispatch_get_main_queue(), ^{
                  completion(credential, error);
                });
              }
            };
        NSString *eventID = [FIRAuthWebUtils randomStringWithLength:10];
        NSString *sessionID = [FIRAuthWebUtils randomStringWithLength:10];
    //    __strong __typeof__(self) strongSelf = weakSelf;
        [self
            getHeadFulLiteURLWithEventID:eventID
                               sessionID:sessionID
                              completion:^(NSURL *_Nullable headfulLiteURL, NSError *_Nullable error) {
                                if (error) {
                                  callbackOnMainThread(nil, error);
                                  return;
                                }
                                FIRAuthURLCallbackMatcher callbackMatcher =
                                    ^BOOL(NSURL *_Nullable callbackURL) {
                                      return [FIRAuthWebUtils
                                          isExpectedCallbackURL:callbackURL
                                                        eventID:eventID
                                                       authType:kAuthTypeSignInWithRedirect
                                                 callbackScheme:self->_callbackScheme];
                                    };
    //                            __strong FIRAuth *strongAuth = weakAuth;
                                [_auth.authURLPresenter
                                         presentURL:headfulLiteURL
                                         UIDelegate:UIDelegate
                                    callbackMatcher:callbackMatcher
                                         completion:^(NSURL *_Nullable callbackURL,
                                                      NSError *_Nullable error) {
                                           if (error) {
                                             callbackOnMainThread(nil, error);
                                             return;
                                           }
                                           NSString *OAuthResponseURLString =
                                               [self OAuthResponseForURL:callbackURL
                                                                         error:&error];
                                           if (error) {
                                             callbackOnMainThread(nil, error);
                                             return;
                                           }
                                           __strong NSString *strongProviderID = _providerID;
                                           FIROAuthCredential *credential = [[FIROAuthCredential alloc]
                                                   initWithProviderID:strongProviderID
                                                            sessionID:sessionID
                                               OAuthResponseURLString:OAuthResponseURLString];
                                           callbackOnMainThread(credential, nil);
                                         }];
                              }];
      });
    }
    
    Login or Signup to reply.
  3. For me there was no need in framework modifications.

    As stated in a issue on GitHub: provider property should be

    declared at a class or global level

    So I just moved its initialisation out of a function.

    Before:

    class AuthViewController: UIViewController {
       private func signIn() {
          let provider = OAuthProvider(providerID: "twitter.com")
          provider.getCredentialWith(nil) { 
             ...
          }
       }
    }
    

    After:

    class AuthViewController: UIViewController {
       private let provider = OAuthProvider(providerID: "twitter.com")
       private func signIn() {
          provider.getCredentialWith(nil) { 
             ...
          }
       }
    }
    
    Login or Signup to reply.
  4. Got stucked in about:blank page for days, tried all the above but not working, solved by add following code in AppDelegate

    func application(_ app: UIApplication, open url: URL, options: func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        let twitterhandeled = Auth.auth().canHandle(url)
        return twitterhandeled
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search