In questa lezione entreremo nel vivo dell’integrazione del servizio Firebase Authentication all’interno di un’applicazione iOS (appena creata come illustrato nella precedente lezione) sfruttando il social login tramite Facebook.
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
use_frameworks!
...
pod 'FBSDKCoreKit'
pod 'FBSDKShareKit'
pod 'FBSDKLoginKit'
end
L’aggiunta di queste tre SDK, offre una completa integrazione della piattaforma nella nostra applicazione, permettendo non solo di effettuare l’autenticazione ma anche la condivisione di stati ed elementi dall’applicazione su Facebook. Se fossimo solo interessati al servizio di autenticazione di Facebook, basterà aggiungere al Podfile quanto segue:
pod 'FBSDKLoginKit'
Una volta salvato e chiuso il file, da terminale eseguire il comando:
pod install
Ciò effettuerà l’installazione dei pods di Facebook nel workspace, ottenendo l’output seguente.
Si ricorda che nella precedente lezione sono stati installati i pod Core
e Auth
di Firebase.
Modifica del file Info.plist
Per permettere all’applicazione di sfruttare il meccanismo di autenticazione di Facebook è necessario modificare il file Info.plist aggiungendo le informazioni relative all’applicazione ottenute durante la fase di registrazione sulla piattaforma. In particolare, questa procedura è illustrata nella lezione 2.
Aprire il file Info.plist come codice sorgente (click con il tasto destro -> Apri come -> Codice sorgente) ed integrare le informazioni recuperate all’inizio della sezione <dict>
come segue:
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb118446748837203</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>118446748837203</string>
<key>FacebookDisplayName</key>
<string>SocialLoginHTMLit</string>
…
</dict>
Per permettere all’applicazione di usare una delle finestre di dialogo di Facebook, come l’accesso o la condivisione, è necessario aggiungere nel dizionario quanto segue:
<dict>
...
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
…
</dict>
Salvare e chiudere il file.
Modifica dell’AppDelegate
Per inizializzare l’SDK di Facebook all’avvio dell’applicazione, bisogna importare nell’AppDelegate la FBSDKCoreKit
come segue
Swift
import FBSDKCoreKit
Objective-C
#import <FBSDKCoreKit/FBSDKCoreKit.h>
Successivamente, all’interno della funzione application richiamiamo il metodo d’istanza application:didFinishLaunchingWithOptions
di FBSDKApplicationDelegate
come segue:
Swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
...
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
Objective-C
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
return YES;
}
Infine, per interagire con l’applicazione nativa di Facebook (o con la sua versione web tramite Safari) e gestirne correttamente le risposte è necessario implementare il metodo application:openURL:options
come segue.
Swift
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let handled = FBSDKApplicationDelegate.sharedInstance().application(app,
open: url,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!,
annotation: options[UIApplicationOpenURLOptionsKey.annotation])
return handled
}
Objective-C
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
return handled;
}
Integrazione del bottone di login
Integriamo, infine, il bottone di login per effettuare l’autenticazione tramite Facebook con Firebase.
Per farlo, aprire il file ViewController ed importare le librerie di Facebook e Firebase.
Swift
import Firebase
import FBSDKLoginKit
Objective-C
@import Firebase;
#import <FBSDKLoginKit/FBSDKLoginKit.h>
Successivamente, modificare la funzione viewDidLoad
per effettuare la creazione del bottone:
Swift
override func viewDidLoad() {
let loginButton = FBSDKLoginButton()
loginButton.delegate = self
loginButton.center = view.center
loginButton.readPermissions = ["email", "public_profile"]
view.addSubview(loginButton)
}
Objective-C
- (void)viewDidLoad {
[super viewDidLoad];
FBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init];
loginButton.center = self.view.center;
loginButton.readPermissions = @[@"public_profile", @"email"];
[self.view addSubview:loginButton];
}
Poi, implementiamo il FBSDKLoginButtonDelegate, “delegato” del FBSDKLoginButton
, che permette di comprendere quando il bottone è stato utilizzato per il login e il logout.
Swift
class ViewController: UIViewController , FBSDKLoginButtonDelegate {
…
}
Objective-C
@interface ViewController : UIViewController <FBSDKLoginButtonDelegate>
Per integrare del tutto il FBSDKLoginButtonDelegate
, è necessario implementare i metodi seguenti:
Metodo | Utilizzo |
---|---|
loginButton |
per effettuare il login |
loginButtonDidLogOut |
per effettuare il logout |
Per quanto riguarda la funzione loginButton
, la sua implementazione può essere definita nei seguenti punti:
- effettuiamo il login tramite Facebook;
- ci assicuriamo che l’autenticazione sia andata a buon fine;
- recuperiamo l’access token corrente tramite la classe
FBSDKAccessToken
; - effettuiamo il login con Firebase attraverso il metodo
signIn
della classeAuth
(responsabile dell’autenticazione delle app basate su Firebase) e l’access token appena ottenuto da Facebook; - se l’autenticazione è andata a buon fine, estraiamo le informazioni sull’utente, tra cui il nome utente.
Di seguito è riportata una possibile implementazione del loginButton
:
Swift
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil {
print(error.localizedDescription)
return
}
let accessToken = FBSDKAccessToken.current()
guard let accessTokenString = accessToken?.tokenString else { return }
let credential = FacebookAuthProvider.credential(withAccessToken: accessTokenString)
let firebaseAuth = Auth.auth()
firebaseAuth.signIn(with: credential, completion: { (user, error) in
if error != nil {
print("Something went wrong with our FB user: ", error ?? "")
return
}
print("Successfully logged in with our user: ", user ?? "")
let user = firebaseAuth.currentUser
print("Logged in ", user?.displayName)
})
}
Objective-C
- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error {
if (error != nil || result.isCancelled) {
return;
}
FIRAuthCredential *credential = [FIRFacebookAuthProvider
credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString];
[[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
if (error) {
NSLog(@"Something went wrong with our FB user: %@", error)
return;
}
// User successfully signed in. Get user data from the FIRUser object
if (authResult == nil) { return; }
FIRUser *user = authResult.user;
printf("Logged in ", user.displayName)
}];
printf("Logged in")
}
Invece, la funzione di logout può essere definita come segue:
Swift
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
} catch let signOutError as NSError {
print ("Error signing out: %@", signOutError)
}
print("Logged out!")
}
Objective-C
-(void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton {
NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
NSLog(@"Error signing out: %@", signOutError);
return;
}
printf("Logged out")
}
Anche in questo caso, è stata utilizzata la classe Auth
per gestire il processo di login richiamando questa volta il metodo signOut()
per effettuare il logout.
Risultato finale
Eseguiamo ora l’applicazione su un dispositivo mobile o sull’emulatore ottenendo la seguente schermata.
Cliccando sul bottone, verrà concesso all’utente di autenticarsi con il proprio account Facebook, chiedendogli l’autorizzazione per l’accesso ai dati personali da parte dell’applicazione.
Una volta autenticato, l’utente viene reindirizzato nuovamente nella schermata di login ma al posto del bottone di autenticazione verrà visualizzato il bottone per il logout e il nome dell'utente.
Il codice sorgente di questa sezione è disponibile su GitHub.