Arquitetura Firebase Authentication com SwiftUI

Muitas aplicações precisam saber a identidade do usuário para promover regras de seguranças eficientes e oferecer experiências customizadas. Com Firebase Authentication é possível autenticar o usuário com vários provedores, como Facebook, Twitter, GitHub, Google e Apple, tudo isso com uma interface de login própria ou utilizando uma já pronta do Google, que pode ser customizada.

Vamos ver como o Firebase Authentication pode ser integrado em uma aplicação construída SwiftUI 2.0!

Implementação:

Depois de ter criado o projeto no Firebase e também no Xcode, além de executar todos os passos de preparação, como pode ser visto nesse link, é necessário adicionar as bibliotecas do Firebase ao projeto, que nesse exemplo foi feito baseado no CocoaPods. Por isso, no arquivo Podfile, adicione as seguintes linhas:

Com essas bibliotecas será possível utilizar o Firebase Authentication, incluindo sua interface gráfica padrão para o usuário escolher o provedor de autenticação, que nesse exemplo será feito através da conta do Google. Lembrando que é necessário habilitar a autenticação com a conta do Google no console do Firebase Authentication, para que o usuário possa utilizar esse provedor.

Dentro do arquivo principal da aplicação, aquele que está anotado com @main, inicialize o Firebase dentro de sua função init, como no trecho a seguir:

Isso vai fazer com que o Firebase Authentication possa ser utilizado, depois que o app for inicializado.

A ideia é fazer com que a tela principal seja responsável por controlar o fluxo de autenticação do usuário, para isso é necessário criar um viewModel que represente e publique esse estado. Dessa forma, ele poderia ser utilizado para receber os eventos de autenticação do Firebase. Veja como isso poderia ser feito:

Veja que essa classe está em conformidade com o protocolo ObservableObject<, o que permite que ele publique alterações no estado de autenticação do usuário, para ser observado por qualquer view. Esse estado está representado pelo atributo @Published var isLogged = false, declarado logo no início desse classe.

Perceba também que a classe está em conformidade com o protocolo FUIAuthDelegate, que exige a implementação da função authUI, que é onde nossa aplicação será informada quando o usuário concluir o processo de autenticação.

A função init, dessa classe basicamente configura a interface padrão do FirebaseUI para utilizar o Google como provedor de autenticação e também configura seu delegate como sendo sua própria instância.

Por último, essa classe possui a função signOut, que pode ser chamada por qualquer view para efetuar o processo de logout do usuário.

Veja que em todos os casos de login e logout do usuário, a variável isLogged, tem seu valor alterado para refletir o estado de autenticação do usuário. Isso faz com que quem estiver observando a instância de AuthenticationViewModel, será notificado dessa alteração, como será visto a seguir.

Para de fato exibir a tela de login ao usuário, é necessário criar uma instância de AuthViewController. Para que isso seja possível em um projeto SwiftUI, é necessário criar uma view que esteja em conformidade com o protocolo UIViewControllerRepresentable, como pode ser visto no trecho a seguir:

Dentro da função makeUIViewController, será criada a tela que será apresentada ao usuário, com os provedores que foram configurados para isso.

Essa view será chamada na tela principal da aplicação, caso o usuário não tenha se autenticado ainda, como pode ser visto no trecho a seguir:

Veja que o atributo isLogged de AuthenticationViewModel, que está sendo observado dentro de ContentView, controla a exibição da tela principal da aplicação, que por enquanto contém só uma mensagem de boas vindas. Caso o usuário ainda não esteja logado, a tela de login com a lista de provedores, que foi criada em LoginView, será exibida de acordo com o que foi configurado em AuthenticationViewModel.

Quando o usuário concluir o processo de autenticação esse AuthenticationViewModel irá publicar um evento, informando que seu atributo isLogged alterou seu estado para true, fazendo com que o SwiftUI redesenha ContentView, que agora passará a exibir o texto com a mensagem de boas vindas.

Ainda em ContentView, perceba que existe um botão para que o usuário faça o logout da aplicação. Esse botão na verdade chama a função signOut de AuthenticationViewModel que, além de fazer o processo de logout do usuário, publica o estado false em seu atributo isLogged. Por sua vez, o SwiftUI irá redesenhar a tela principal do app, exibindo novamente a tela de login.

Obviamente, existem outras abordagens para controlar o fluxo de autenticação do usuário, mas esse é um exemplo simples e fácil de ser construído.

Referência:

Esse artigo foi baseado nos conceitos ministrados nesse livro: Livro - Desenvolvimento iOS com Firebase