Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Google login su iOS con Firebase

Come utilizzare Firebase per implementare l'autenticazione tramite Google (social login) all'interno di un'app mobile per iOS.
Come utilizzare Firebase per implementare l'autenticazione tramite Google (social login) all'interno di un'app mobile per iOS.
Link copiato negli appunti

In questa lezione illustreremo i passi per aggiungere il social login di Google tramite il servizio Firebase Authentication a partire da un’applicazione iOS appena creata, come illustrato nella precedente lezione.

Configurazione del PodFile

Per iniziare l’integrazione, il primo passo da compiere è l’aggiunta della SDK di Facebook attraverso la modifica del Podfile inizializzato in precedenza.

Aprire il Podfile con un qualsiasi editor di testo e aggiungere le SDK di Facebook nell’apposita sezione come segue:

target 'SocialLoginHMTLit' do
. . .
pod 'GoogleSignIn’
end

Una volta salvato e chiuso il file, da terminale eseguiamo il comando:

pod install

Esso effettua l’installazione del pod nel progetto e crea il nuovo workspace da usare per lo sviluppo. In caso di corretta installazione, il terminale mostrerà un output simile al seguente.

Figura 100. Output del comando "pod install" (click per ingrandire)


Output del comando "pod install"

Si ricorda che nella lezione 19 sono stati installati i pod Core e Auth di Firebase, altrettanto necessari per i nostri scopi.

Modifica dell’URL Schemes

Per permettere all’applicazione di utilizzare il meccanismo di autenticazione di Google, devono essere aggiunti due URL Scheme al progetto:

  • il reversed client ID, presente nel GoogleService-Info.plist;
  • il bundle ID.

Nel tab Info delle configurazioni del progetto, espandiamo la sezione URL Types e clicchiamo sul pulsante + riportando nella textbox dell’URL Schemes il reversed client ID (reperibile nel GoogleService-Info.plist). Ripetiamo la medesima operazione riportando questa volta il bundle ID e otterremo il seguente risultato.

Figura 101. Sezione URL Schemes del progetto (click per ingrandire)


Sezione URL Schemes del progetto

Modifica dell’AppDelegate

Per inizializzare l’SDK di Google all’avvio dell’applicazione, importiamo nell’AppDelegate la classe GoogleSignIn

Swift

import GoogleSignIn

Objective-C
//Nel file .h
@import GoogleSignIn;

La classe GoogleSignIn offre il single sign-on tramite un’applicazione di Google già abilitata o in assenza attraverso il browser.

Successivamente, va implementata la classe GIDSignInDelegate che definisce un protocollo utilizzato dal delegato del GIDSignIn. Al termine della comunicazione verrà restituito all’applicazione un nuovo token o, in caso di fallimento, un errore.

Swift

class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
…
}

Objective-C
//Aggiungere nel file .h
@interface AppDelegate : UIResponder <UIApplicationDelegate, GIDSignInDelegate>

Inizializziamo il GIDSignIn impostando il client ID e il delegate nel metodo application:didFinishLaunchingWithOptions:

Swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
. . .
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
return true
}

Objective-C
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
. . .
[GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
[GIDSignIn sharedInstance].delegate = self;
return YES;
}

Implementiamo ora il metodo application:openURL:options.

Swift

func application(application: UIApplication,
openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
var options: [String: AnyObject] = [UIApplicationOpenURLOptionsSourceApplicationKey: sourceApplication,
UIApplicationOpenURLOptionsAnnotationKey: annotation]
return GIDSignIn.sharedInstance().handleURL(url,
sourceApplication: sourceApplication,
annotation: annotation)
}

Objective-C
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}

Come è possibile notare, è stato invocato il metodo handleURL dell’istanza GIDSignIn per gestire correttamente l’URL inviata all’applicazione al termine del processo di autenticazione.

Infine, non resta che definire una possibile implementazione del metodo di login.

Swift

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
print("\(error.localizedDescription)")
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotification"), object: nil, userInfo: nil)
}
guard let authentication = user.authentication else { return }
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
accessToken: authentication.accessToken)
Auth.auth().signIn(with: credential) { (user, error) in
if (error) != nil {
print("Google Authentification Fail")
} else {
print("Google Authentification Success")
if let displayName = user?.displayName{
print(displayName)
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotification"),
object: nil,
userInfo: ["statusText": "Hi \(displayName)!"])
}
}
}
}

Objective-C
- (void)signIn:(GIDSignIn *)signIn
didSignInForUser:(GIDGoogleUser *)user
withError:(NSError *)error {
if (error == nil) {
GIDAuthentication *authentication = user.authentication;
FIRAuthCredential *credential =
[FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
accessToken:authentication.accessToken];
NSString *fullName = user.profile.name;
NSDictionary *statusText = @{@"statusText":
[NSString stringWithFormat:@"Hi %@", fullName]};
[[NSNotificationCenter defaultCenter] postNotificationName:@"ToggleAuthUINotification" object:nil userInfo:statusText];
}
}

Ricapitolando:

  • è stata effettuata l’autenticazione tramite Google;
  • sono state create le credenziali di accesso tramite il metodo credential() della classe GoogleAuthProvider;
  • le credenziali così ottenute sono state utilizzate per autenticare l’utente tramite il metodo signIn della classe Auth (responsabile dell’autenticazione delle app basate su Firebase);
  • è stato estratto il displayName dell’utente corrente per mostrarlo in una UILabel tramite il NotificationCenter e impostando il postNotificationName a ToggleAuthUINotification e il campo userInfo a statusText per la visualizzazione del nome utente.

Aggiunta del pulsante di login

Aggiungiamo, infine, il pulsante di autenticazione nella schermata principale.

Nella Main.storyboard selezioniamo l'oggetto View dall’Object Library e posizioniamolo al centro della schermata. Impostiamo, poi, la classe della View a GIDSignInButton.

Figura 102. Definizione della Custom Class per la view (click per ingrandire)


Definizione della Custom Class per la view

Avendo creato il pulsante come un oggetto View, questo non verrà visualizzato all’interno della schermata.

Colleghiamo poi il bottone di login con il codice del ViewController per creare il seguente IBOutlet:

Swift

@IBOutlet weak var signInButton: GIDSignInButton!

Objective-C
@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton;

Nel corpo del metodo viewDidLoad, impostiamo il UiDelegate e il NotificationCenter come segue

Swift

override func viewDidLoad() {
. . .
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().signIn()
NotificationCenter.default.addObserver(self,
selector: #selector(ViewController.receiveToggleAuthUINotification(_:)),
name: NSNotification.Name(rawValue: "ToggleAuthUINotification"),
object: nil)
. . .
}

Objective-C
- (void)viewDidLoad {
. . .
[GIDSignIn sharedInstance].uiDelegate = self;
[[GIDSignIn sharedInstance] signIn];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(receiveToggleAuthUINotification:)
name:@"ToggleAuthUINotification"
object:nil];
. . .
}

In questo modo, abbiamo aggiunto un Observer alla schermata corrente in modo da estrarre la userInfo impostata nell’AppDelegate attraverso il metodo receiveToggleAuthUINotification impostato come selector e implementato come segue:

Swift

@objc func receiveToggleAuthUINotification(_ notification: NSNotification) {
if notification.name.rawValue == "ToggleAuthUINotification" {
. . .
if notification.userInfo != nil {
guard let userInfo = notification.userInfo as? [String:String] else { return }
self.statusText.text = userInfo["statusText"]!
}
}
}

Objective-C
- (void) receiveToggleAuthUINotification:(NSNotification *) notification {
if ([notification.name isEqualToString:@"ToggleAuthUINotification"]) {
. . .
self.statusText.text = notification.userInfo[@"statusText"];
}
}

Aggiungiamo ora il pulsante di logout.

Nella Main.storyboard, selezioniamo l'oggetto UIButton dall’Object Library e posizioniamolo al centro della schermata. Successivamente, impostiamo il testo del pulsante a Sign Out e lo sfondo a grigio attraverso la proprietà background dell’Attribute Inspector.

Colleghiamo poi il bottone con il codice del ViewController per creare un @IBOutlet di tipo UIButton e aggiungiamo un nuovo metodo per il logout da Google e Firebase come segue.

Swift

@IBAction func didTapSignOut(_ sender: AnyObject) {
GIDSignIn.sharedInstance().signOut()
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
statusText.text = "Signed out"
toggleAuthUI()
} catch let signOutError as NSError {
print ("Error signing out: %@", signOutError)
}
}

Objective-C
- (IBAction)didTapSignOut:(id)sender {
[[GIDSignIn sharedInstance] signOut];
NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
NSLog(@"Error signing out: %@", signOutError);
return;
}
[self toggleAuthUI];
}

In questo modo, l’utente verrà disconnesso sia da Google che da Firebase e in caso di fallimento verrà mostrato un messaggio di errore.

Colleghiamo infine il bottone di logout al metodo didTapSignOut.

Inseriamo ora una label di tipo UILabel per mostrare il nome dell’utente loggato posizionandola sopra il bottone di logout e collegandola al codice, come fatto in precedenza.

Gestiamo infine, la visibilità dei bottoni creati e del testo della label attraverso il seguente metodo.

Swift

func toggleAuthUI() {
if GIDSignIn.sharedInstance().hasAuthInKeychain() {
signInButton.isHidden = true
signOutButton.isHidden = false
} else {
signInButton.isHidden = false
signOutButton.isHidden = true
statusText.text = "Google Sign in"
}
}

Objective-C
- (void)toggleAuthUI {
if ([GIDSignIn sharedInstance].currentUser.authentication != nil) {
self.signInButton.hidden = YES;
self.signOutButton.hidden = NO;
} else {
self.signInButton.hidden = NO;
self.signOutButton.hidden = YES;
self.statusText.text = @"Google Sign in";
}
}

Questa funzione nasconderà il pulsante di login in caso di login, mostrando quello di logout. Contrariamente, in caso di fallimento, verrà visualizzato il pulsante di login e reimpostato il testo della label.

Per completare le modifiche, richiamiamo il metodo toggleAuthUI nei seguenti metodi:

  • viewDidLoad;
  • didTapSignOut;
  • receiveToggleAuthUINotification.

Risultato finale

All’avvio dell’applicazione sul dispositivo mobile o sull’emulatore, verrà mostrata la schermata contenente il pulsante di default precedentemente aggiunto all’interfaccia.

Figura 103. Schermata di autenticazione con Google (click per ingrandire)


Schermata di autenticazione con Google

Cliccando sul pulsante, verrà richiesto all’utente di autenticarsi con il proprio account Google e di accettare i termini del servizio.

Figura 104. Schermata di autenticazione di Google (click per ingrandire)


Schermata di autenticazione di Google

Una volta autenticato, l’utente viene rimandato nuovamente alla scheramta di avvio dove sarà visualizzato il nome dell’utente e il pulsante di logout, come in figura.

Figura 105. Schermata principale dopo l’autenticazione dell’utente tramite Google (click per ingrandire)


Schermata principale dopo l’autenticazione dell’utente tramite Google

Cliccando sul pulsante di sign out, l’utente verrà disconnesso.

Il codice sorgente di questa sezione è disponibile su GitHub.

Ti consigliamo anche