<h3>Google Sign In</h3>
<p>Hey everyone, welcome back! In the last episode, we discussed how to install and integrate the Firebase SDK to authenticate our Facebook user. You can watch that episode at <a href="/playlist/Firebase-Social-Login/video/Firebase-SDK-and-Sign-In-Facebook-User">Firebase SDK and Sign In Facebook User</a>.</p>
<h4>Today's Episode</h4>
For our lesson today, I wanted to show you how to do three things:
<ul>
<li>Install Google Sign In SDK using Cocoapods</li>
<li>Setup our project with the Google Sign In button</li>
<li>Configure our project to enable Google authentication</li>
<li>Sign in to Firebase using our Google credentials</li>
</ul>
<h4>Getting Started</h4>
Obviously, if you haven't downloaded the project from the last episode, please go ahead and download it at the bottom of <a href="/playlist/Firebase-Social-Login/video/Firebase-SDK-and-Sign-In-Facebook-User">this page</a>. If you would like to follow the <a href="https://firebase.google.com/docs/auth/ios/google-signin">Official Firebase Guide</a>, you can do that as well.
</br></br>
<h4>Edit ViewController.swift</h4>
Go ahead and open ViewController.swift and setup the Google Sign In button like this:
<br/><br/>
<div class='filename'>ViewController.swift
!codebreak
!syntax-highlight
override func viewDidLoad() {
super.viewDidLoad()
setupFacebookButtons()
setupGoogleButtons()
}
fileprivate func setupGoogleButtons() {
//add google sign in button
let googleButton = GIDSignInButton()
googleButton.frame = CGRect(x: 16, y: 116 + 66, width: view.frame.width - 32, height: 50)
view.addSubview(googleButton)
}
fileprivate func setupFacebookButtons() {
let loginButton = FBSDKLoginButton()
view.addSubview(loginButton)
//frame's are obselete, please use constraints instead because its 2016 after all
loginButton.frame = CGRect(x: 16, y: 50, width: view.frame.width - 32, height: 50)
loginButton.delegate = self
loginButton.readPermissions = ["email", "public_profile"]
//add our custom fb login button here
let customFBButton = UIButton(type: .system)
customFBButton.backgroundColor = .blue
customFBButton.frame = CGRect(x: 16, y: 116, width: view.frame.width - 32, height: 50)
customFBButton.setTitle("Custom FB Login here", for: .normal)
customFBButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
customFBButton.setTitleColor(.white, for: .normal)
view.addSubview(customFBButton)
customFBButton.addTarget(self, action: #selector(handleCustomFBLogin), for: .touchUpInside)
}
!codebreak
<br/>
Running the application now, you'll see the lovely Google Sign In button:
<br/><br/><img style="border-style: solid; border-width: 1px; border-color: #CCCCCC; max-width: 100%" src="https://letsbuildthatapp-videos.s3-us-west-2.amazonaws.com/1c7a0711-66f4-4836-857d-623b80d17413"/><br/><br/>
<br/>
<h4>Let's Fix Some Errors</h4>
Notice that if you click on the Google Sign In Button, the application will crash telling you to set the clientId properly. Implement this fix in <b>AppDelegate</b>
<br/><br/>
<div class='filename'>AppDelegate.swift
!codebreak
!syntax-highlight
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
GIDSignIn.sharedInstance().clientID = FIRApp.defaultApp()?.options.clientID
return true
}
!codebreak
<br/>
You'll get a different error after running the application again. This time, clicking on sign in will give you an error telling you to fix uiDelegate. Implement this fix:
<br/><br/>
<div class='filename'>AppDelegate.swift
!codebreak
!syntax-highlight
fileprivate func setupGoogleButtons() {
//add google sign in button
let googleButton = GIDSignInButton()
googleButton.frame = CGRect(x: 16, y: 116 + 66, width: view.frame.width - 32, height: 50)
view.addSubview(googleButton)
GIDSignIn.sharedInstance().uiDelegate = self
}
!codebreak
<br/><br/>
Finally, running the application will crash again telling you to insert your <b>REVERSE_CLIENT_ID</b> into your url schemes. You can find the appropriate value in your <b>Google-Info.plist</b> file. Insert it into your project settings like this:
<br/>
<br/><img style="border-style: solid; border-width: 1px; border-color: #CCCCCC; max-width: 100%" src="https://letsbuildthatapp-videos.s3-us-west-2.amazonaws.com/10838d3c-7731-450b-bd2a-f32a2228c0b4"/><br/><br/>
Now with all these fixes, you can at last authenticate with Google after clicking sign in:
<br/><br/><img style="border-style: solid; border-width: 1px; border-color: #CCCCCC; max-width: 100%" src="https://letsbuildthatapp-videos.s3-us-west-2.amazonaws.com/5e3ed468-2b46-4dc9-b04a-b785cf44debd"/><br/><br/>
<h4>Allow application to receive credentials</h4>
Being able to authenticate yourself through Google is great, however you'll notice the application is transitioning back to your app after authentication. Fix this by implementing this inside AppDelegate:
<br/><br/>
<div class='filename'>AppDelegate.swift
!codebreak
!syntax-highlight
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])
GIDSignIn.sharedInstance().handle(url,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!,
annotation: options[UIApplicationOpenURLOptionsKey.annotation])
return handled
}
!codebreak
<br/>
After authentication, your application will now receive the credentials from Google.
<br/><br/>
<h4>Receive Sign In</h4>
One final bit of code to implement is the actual bit that tells us the user has signed in. Inside AppDelegate, conform to the <b>GIDSignInDelegate</b> protocol and setup the GIDSignIn delegate:
<br/><br/>
<div class='filename'>AppDelegate.swift
!codebreak
!syntax-highlight
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
//...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//...
GIDSignIn.sharedInstance().delegate = self
//...
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let err = error {
print("Failed to log into Google: ", err)
return
}
print("Successfully logged into Google", user)
}
}
!codebreak
Run the application and sign in to Google. You'll see the successful logged in print statement in the console.
<br/><br/>
<h4>Firebase Sign In with Google</h4>
Looks like all the hard work is done to authenticate ourselves with Google. The final step now is to sign into Firebase with our Google credentials. We'll do this by augmenting the didSignIn function like this:
<br/><br/>
<div class='filename'>AppDelegate.swift
!codebreak
!syntax-highlight
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
//...
print("Successfully logged into Google", user)
guard let idToken = user.authentication.idToken else { return }
guard let accessToken = user.authentication.accessToken else { return }
let credentials = FIRGoogleAuthProvider.credential(withIDToken: idToken, accessToken: accessToken)
FIRAuth.auth()?.signIn(with: credentials, completion: { (user, error) in
if let err = error {
print("Failed to create a Firebase User with Google account: ", err)
return
}
guard let uid = user?.uid else { return }
print("Successfully logged into Firebase with Google", uid)
})
}
!codebreak
<br/>
Run your application and sign into Google again. You will probably have to enable the Google Sign In method in Firebase if you haven't done so already:
<br/><br/><img style="border-style: solid; border-width: 1px; border-color: #CCCCCC" src="https://letsbuildthatapp-videos.s3-us-west-2.amazonaws.com/a154cf74-4e72-49f0-9368-cc2ecb80a3a8"/><br/><br/>
Sign into Google again and you should now have your user inside of Firebase Authentication:
<br/><br/><img style="border-style: solid; border-width: 1px; border-color: #CCCCCC; max-width: 100%" src="https://letsbuildthatapp-videos.s3-us-west-2.amazonaws.com/27b46af3-4281-47a2-9dbc-2eebd08ca92b"/><br/><br/>