Autenticar usando o Twitter em plataformas Apple

Você pode permitir que seus usuários se autentiquem com o Firebase usando provedores OAuth como o Twitter, integrando o login genérico do OAuth ao seu aplicativo usando o SDK do Firebase para realizar o fluxo de login de ponta a ponta.

Antes de você começar

Use o Swift Package Manager para instalar e gerenciar dependências do Firebase.

  1. No Xcode, com o projeto do seu aplicativo aberto, navegue até File > Add Packages .
  2. Quando solicitado, adicione o repositório SDK das plataformas Apple do Firebase:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Escolha a biblioteca Firebase Authentication.
  5. Adicione o sinalizador -ObjC à seção Outros sinalizadores de vinculador das configurações de compilação do seu destino.
  6. Quando terminar, o Xcode começará automaticamente a resolver e baixar suas dependências em segundo plano.

Para fazer login de usuários usando contas do Twitter, primeiro você precisa ativar o Twitter como provedor de login para seu projeto do Firebase:

  1. Adicione o Firebase ao seu projeto Apple .

  2. Inclua os seguintes pods em seu Podfile :

    pod 'FirebaseAuth'
  3. No console do Firebase , abra a seção Auth .
  4. Na guia Método de login , habilite o provedor do Twitter .
  5. Adicione a chave de API e o segredo de API do console do desenvolvedor desse provedor à configuração do provedor:
    1. Registre seu aplicativo como um aplicativo de desenvolvedor no Twitter e obtenha a chave da API OAuth e o segredo da API do seu aplicativo.
    2. Certifique-se de que seu URI de redirecionamento do Firebase OAuth (por exemplo, my-app-12345.firebaseapp.com/__/auth/handler ) esteja definido como seu URL de retorno de chamada de autorização na página de configurações do seu aplicativo na configuração do seu aplicativo do Twitter .
  6. Clique em Salvar .

Lidar com o fluxo de login com o SDK do Firebase

Para lidar com o fluxo de login com o SDK das plataformas Apple do Firebase, siga estas etapas:

  1. Adicione esquemas de URL personalizados ao seu projeto Xcode:

    1. Abra a configuração do seu projeto: clique duas vezes no nome do projeto na visualização em árvore à esquerda. Selecione seu aplicativo na seção TARGETS , selecione a guia Informações e expanda a seção Tipos de URL .
    2. Clique no botão + e adicione seu ID de aplicativo codificado como um esquema de URL. Você pode encontrar o ID do aplicativo codificado na página Configurações gerais do console do Firebase, na seção do seu aplicativo iOS. Deixe os demais campos em branco.

      Quando concluída, sua configuração deverá ser semelhante à seguinte (mas com os valores específicos do seu aplicativo):

      Captura de tela da interface de configuração do esquema de URL personalizado do Xcode

  2. Crie uma instância de um OAuthProvider usando o ID do provedor twitter.com .

        var provider = OAuthProvider(providerID: "twitter.com")
       
        FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"twitter.com"];
       
  3. Opcional : Especifique parâmetros OAuth customizados adicionais que você deseja enviar com a solicitação OAuth.

        provider.customParameters = [
         
    "lang": "fr"
         
    ]
       
        [provider setCustomParameters:@{@"lang": @"fr"}];
       

    Para os parâmetros suportados pelo Twitter, consulte a documentação do Twitter OAuth . Observe que você não pode transmitir parâmetros exigidos pelo Firebase com setCustomParameters . Esses parâmetros são client_id , redirect_uri , response_type , scope e state .

  4. Opcional : se você quiser personalizar a forma como seu aplicativo apresenta o SFSafariViewController ou UIWebView ao exibir o reCAPTCHA para o usuário, crie uma classe personalizada que esteja em conformidade com o protocolo AuthUIDelegate e passe-a para credentialWithUIDelegate .

  5. Autentique-se com o Firebase usando o objeto do provedor OAuth.

        provider.getCredentialWith(nil) { credential, error in
         
    if error != nil {
           
    // Handle error.
         
    }
         
    if credential != nil {
           
    Auth.auth().signIn(with: credential) { authResult, error in
             
    if error != nil {
               
    // Handle error.
             
    }
             
    // User is signed in.
             
    // IdP data available in authResult.additionalUserInfo.profile.
             
    // Twitter OAuth access token can also be retrieved by:
             
    // (authResult.credential as? OAuthCredential)?.accessToken
             
    // Twitter OAuth ID token can be retrieved by calling:
             
    // (authResult.credential as? OAuthCredential)?.idToken
             
    // Twitter OAuth secret can be retrieved by calling:
             
    // (authResult.credential as? OAuthCredential)?.secret
           
    }
         
    }
       
    }
       
        [provider getCredentialWithUIDelegate:nil
                                   completion
    :^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
         
    if (error) {
           
    // Handle error.
         
    }
         
    if (credential) {
           
    [[FIRAuth auth] signInWithCredential:credential
                                      completion
    :^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
             
    if (error) {
               
    // Handle error.
             
    }
             
    // User is signed in.
             
    // IdP data available in authResult.additionalUserInfo.profile.
             
    // Twitter OAuth access token can also be retrieved by:
             
    // authResult.credential.accessToken
             
    // Twitter OAuth ID token can be retrieved by calling:
             
    // authResult.credential.idToken
             
    // Twitter OAuth secret can be retrieved by calling:
             
    // authResult.credential.secret
           
    }];
         
    }
       
    }];
       

    Usando o token de acesso OAuth, você pode chamar a API do Twitter .

    Por exemplo, para obter informações básicas de perfil, você pode chamar a API REST, passando o token de acesso no cabeçalho Authorization :

    https://api.twitter.com/labs/1/users?usernames=TwitterDev
  6. Embora os exemplos acima se concentrem em fluxos de login, você também tem a capacidade de vincular um provedor do Twitter a um usuário existente. Por exemplo, você pode vincular vários provedores ao mesmo usuário, permitindo que eles façam login com qualquer um deles.

        Auth().currentUser.link(withCredential: credential) { authResult, error in
         
    if error != nil {
           
    // Handle error.
         
    }
         
    // Twitter credential is linked to the current user.
         
    // IdP data available in authResult.additionalUserInfo.profile.
         
    // Twitter OAuth access token can also be retrieved by:
         
    // (authResult.credential as? OAuthCredential)?.accessToken
         
    // Twitter OAuth ID token can be retrieved by calling:
         
    // (authResult.credential as? OAuthCredential)?.idToken
         
    // Twitter OAuth secret can be retrieved by calling:
         
    // (authResult.credential as? OAuthCredential)?.secret
       
    }
       
        [[FIRAuth auth].currentUser
            linkWithCredential
    :credential
                    completion
    :^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
         
    if (error) {
           
    // Handle error.
         
    }
         
    // Twitter credential is linked to the current user.
         
    // IdP data available in authResult.additionalUserInfo.profile.
         
    // Twitter OAuth access token is can also be retrieved by:
         
    // ((FIROAuthCredential *)authResult.credential).accessToken
         
    // Twitter OAuth ID token can be retrieved by calling:
         
    // ((FIROAuthCredential *)authResult.credential).idToken
         
    // Twitter OAuth secret can be retrieved by calling:
         
    // ((FIROAuthCredential *)authResult.credential).secret
       
    }];
       
  7. O mesmo padrão pode ser usado com reauthenticateWithCredential , que pode ser usado para recuperar credenciais novas para operações confidenciais que exigem login recente.

        Auth().currentUser.reauthenticateWithCredential(withCredential: credential) { authResult, error in
         
    if error != nil {
           
    // Handle error.
         
    }
         
    // User is re-authenticated with fresh tokens minted and
         
    // should be able to perform sensitive operations like account
         
    // deletion and email or password update.
         
    // IdP data available in result.additionalUserInfo.profile.
         
    // Additional OAuth access token is can also be retrieved by:
         
    // (authResult.credential as? OAuthCredential)?.accessToken
         
    // Twitter OAuth ID token can be retrieved by calling:
         
    // (authResult.credential as? OAuthCredential)?.idToken
         
    // Twitter OAuth secret can be retrieved by calling:
         
    // (authResult.credential as? OAuthCredential)?.secret
       
    }
       
        [[FIRAuth auth].currentUser
            reauthenticateWithCredential
    :credential
                              completion
    :^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
         
    if (error) {
           
    // Handle error.
         
    }
         
    // User is re-authenticated with fresh tokens minted and
         
    // should be able to perform sensitive operations like account
         
    // deletion and email or password update.
         
    // IdP data available in result.additionalUserInfo.profile.
         
    // Additional OAuth access token is can also be retrieved by:
         
    // ((FIROAuthCredential *)authResult.credential).accessToken
         
    // Twitter OAuth ID token can be retrieved by calling:
         
    // ((FIROAuthCredential *)authResult.credential).idToken
         
    // Twitter OAuth secret can be retrieved by calling:
         
    // ((FIROAuthCredential *)authResult.credential).secret
       
    }];
       

Se você ativou a configuração Uma conta por endereço de e-mail no console do Firebase , quando um usuário tenta fazer login em um provedor (como o Twitter) com um e-mail que já existe para o provedor de outro usuário do Firebase (como o Google), o erro FIRAuthErrorCodeAccountExistsWithDifferentCredential é lançado junto com um objeto FIRAuthCredential temporário (credencial do Twitter). Para concluir o login no provedor pretendido, o usuário deve primeiro fazer login no provedor existente (Google) e depois vincular-se ao antigo FIRAuthCredential (credencial do Twitter). Isso ficaria conforme ilustrado abaixo:

  // Sign-in with an OAuth credential.
  provider
.getCredentialWith(nil) { credential, error in
   
// An account with the same email already exists.
   
if (error as NSError?)?.code == AuthErrorCode.accountExistsWithDifferentCredential.rawValue {
     
// Get pending credential and email of existing account.
      let existingAcctEmail
= (error! as NSError).userInfo[AuthErrorUserInfoEmailKey] as! String
      let pendingCred
= (error! as NSError).userInfo[AuthErrorUserInfoUpdatedCredentialKey] as! AuthCredential
     
// Lookup existing account identifier by the email.
     
Auth.auth().fetchProviders(forEmail:existingAcctEmail) { providers, error in
       
// Existing email/password account.
       
if (providers?.contains(EmailAuthProviderID))! {
         
// Existing password account for email. Ask user to provide the password of the
         
// existing account.
         
// Sign in with existing account.
         
Auth.auth().signIn(withEmail:existingAcctEmail, password:password) { user, error in
           
// Successfully signed in.
           
if user != nil {
             
// Link pending credential to account.
             
Auth.auth().currentUser?.linkAndRetrieveData(with: pendingCred) { result, error in
               
// ...
             
}
           
}
         
}
       
}
     
}
     
return
   
}

   
// Other errors.
   
if error != nil {
     
// handle the error.
     
return
   
}

   
// Sign in with the credential.
   
if credential != nil {
     
Auth.auth().signInAndRetrieveData(with: credential!) { result, error in
       
if error != nil {
         
// handle the error.
         
return
       
}
     
}
   
}
 
}

 
  // Sign-in with an OAuth credential.
 
[provider getCredentialWithUIDelegate:nil
                             completion
:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
   
// An account with the same email already exists.
   
if (error.code == FIRAuthErrorCodeAccountExistsWithDifferentCredential) {
     
// Get pending credential and email of existing account.
     
NSString *existingAcctEmail = error.userInfo[FIRAuthErrorUserInfoEmailKey];
     
FIRAuthCredential *pendingCred = error.userInfo[FIRAuthErrorUserInfoUpdatedCredentialKey];
     
// Lookup existing account identifier by the email.
     
[[FIRAuth auth] fetchProvidersForEmail:existingAcctEmail
                                 completion
:^(NSArray<NSString *> *_Nullable providers,
                                             
NSError *_Nullable error) {
       
// Existing email/password account.
       
if ( [providers containsObject:FIREmailAuthProviderID] ) {
         
// Existing password account for email. Ask user to provide the password of the
         
// existing account.

         
// Sign in with existing account.
         
[[FIRAuth auth] signInWithEmail:existingAcctEmail
                                 password
:password
                               completion
:^(FIRUser *user, NSError *error) {
           
// Successfully signed in.
           
if (user) {
             
// Link pending credential to account.
             
[[FIRAuth auth].currentUser linkWithCredential:pendingCred
                                                  completion
:^(FIRUser *_Nullable user,
                                                               
NSError *_Nullable error) {
               
// ...
             
}];
           
}
         
}];
       
}
     
}];
     
return;
   
}

   
// Other errors.
   
if (error) {
     
// handle the error.
     
return;
   
}

   
// Sign in with the credential.
   
if (credential) {
     
[[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
          completion
:^(FIRAuthDataResult *_Nullable authResult,
                       
NSError *_Nullable error) {
       
if (error) {
         
// handle the error.
         
return;
       
}
     
}];
   
}
 
}];
 

Próximos passos

Depois que um usuário faz login pela primeira vez, uma nova conta de usuário é criada e vinculada às credenciais (ou seja, nome de usuário e senha, número de telefone ou informações do provedor de autenticação) com as quais o usuário fez login. Essa nova conta é armazenada como parte do seu projeto do Firebase e pode ser usada para identificar um usuário em todos os aplicativos do seu projeto, independentemente de como o usuário faz login.

  • Nos seus aplicativos, você pode obter as informações básicas do perfil do usuário no objeto User . Consulte Gerenciar usuários .

  • Nas regras de segurança do Firebase Realtime Database e do Cloud Storage , você pode obter o ID de usuário exclusivo do usuário conectado na variável auth e usá-lo para controlar quais dados um usuário pode acessar.

Você pode permitir que os usuários façam login no seu aplicativo usando vários provedores de autenticação vinculando as credenciais do provedor de autenticação a uma conta de usuário existente.

Para desconectar um usuário, chame signOut: .

let firebaseAuth = Auth.auth()
do {
 
try firebaseAuth.signOut()
} catch let signOutError as NSError {
 
print("Error signing out: %@", signOutError)
}
NSError *signOutError;
BOOL status
= [[FIRAuth auth] signOut:&signOutError];
if (!status) {
 
NSLog(@"Error signing out: %@", signOutError);
 
return;
}

Você também pode adicionar código de tratamento de erros para toda a gama de erros de autenticação. Consulte Tratamento de erros .