iOS で Google ログインを使用して認証する

Google ログインをアプリに統合して、ユーザーが Firebase での認証に Google アカウントを使用できるようにすることができます。

準備

  1. Firebase を iOS プロジェクトに追加しますPodfile に次のポッドをインクルードします。
    pod 'Firebase/Auth'
    pod 'GoogleSignIn'
    
  2. アプリを Firebase プロジェクトに接続していない場合は、Firebase console で接続します。
  3. Firebase console で Google ログインを有効にします。
    1. Firebase console で [認証] セクションを開きます。
    2. [ログイン方法] タブで [Google] を有効にし、[保存] をクリックします。

1. 必須ヘッダー ファイルをインポートする

まず Firebase SDK と Google ログイン SDK のヘッダー ファイルをアプリにインポートします。

Objective-C

アプリのデリゲートで、次のヘッダー ファイルをインポートします。

@import Firebase;
@import GoogleSignIn;

ログインビューのビュー コントローラで、次のヘッダー ファイルをインポートします。

@import Firebase;
@import GoogleSignIn;

Swift

アプリのデリゲートで、次のヘッダー ファイルをインポートします。

import Firebase
import GoogleSignIn

ログインビューのビュー コントローラで、次のヘッダー ファイルをインポートします。

import Firebase
import GoogleSignIn

2. Google ログインを実装する

Google ログインを実装する手順は次のとおりです。iOS で Google ログインを使用する方法について詳しくは、Google ログインに関するデベロッパー向けドキュメントをご覧ください。

  1. Xcode プロジェクトにカスタム URL スキームを追加します。
    1. プロジェクトの設定を開きます(左側のツリービューでプロジェクト名をダブルクリックします)。[ターゲット] セクションでアプリを選択し、[情報] タブを開いて [URL タイプ] セクションを展開します。
    2. [+] ボタンをクリックし、反転クライアント ID の URL スキームを追加します。この値を確認するには、GoogleService-Info.plist 設定ファイルを開いて REVERSED_CLIENT_ID キーを探します。見つかったキーの値をコピーし、設定ページの [URL スキーム] ボックスに貼り付けます。その他の入力欄は空白にしておきます。

      完了すると、設定は次のようになります(ただし、値はアプリケーションによって異なります)。

  2. アプリのデリゲートによって GIDSignInDelegate プロトコルを実装することを宣言します。

    Objective-C

    MainViewController.h:
    @interface MainViewController : UITableViewController<GIDSignInDelegate,
                                                          GIDSignInUIDelegate>
    

    Swift

    MainViewController.swift:
    class MainViewController: UITableViewController, GIDSignInDelegate, GIDSignInUIDelegate {
    
  3. アプリのデリゲートの application:didFinishLaunchingWithOptions: メソッドで、FIRApp オブジェクトを設定し、ログインのデリゲートを設定します。

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
    
    [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
    [GIDSignIn sharedInstance].delegate = self;
    

    Swift

    // Use Firebase library to configure APIs
    FIRApp.configure()
    
    GIDSignIn.sharedInstance().clientID = FIRApp.defaultApp()?.options.clientID
    GIDSignIn.sharedInstance().delegate = self
    
  4. アプリのデリゲートに application:openURL:options: メソッドを実装します。このメソッドは GIDSignIn インスタンスの handleURL メソッドを呼び出します。これによって、認証プロセスの最後にアプリが受け取る URL が正しく処理されます。

    Objective-C

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

    Swift

    @available(iOS 9.0, *)
    func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any])
      -> Bool {
        return GIDSignIn.sharedInstance().handleURL(url,
                                sourceApplication:options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
                                annotation: [:])
    }
    }
    

    iOS 8 以前で実行されるアプリの場合は、サポートが終了した application:openURL:sourceApplication:annotation: メソッドも実装します。

    Objective-C

    - (BOOL)application:(UIApplication *)application
                openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
             annotation:(id)annotation {
      return [[GIDSignIn sharedInstance] handleURL:url
                                 sourceApplication:sourceApplication
                                        annotation:annotation];
        

    Swift

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        return GIDSignIn.sharedInstance().handleURL(url,
                                                    sourceApplication: sourceApplication,
                                                    annotation: annotation)
        
  5. アプリのデリゲートで、ログイン プロセスを処理する GIDSignInDelegate プロトコルを実装するために次のメソッドを定義します。

    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];
        // ...
      } else
        // ...
    }
    
    - (void)signIn:(GIDSignIn *)signIn
    didDisconnectWithUser:(GIDGoogleUser *)user
         withError:(NSError *)error {
      // Perform any operations when the user disconnects from app here.
      // ...
    }
    

    Swift

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
      if let error = error {
        // ...
        return
      }
    
      guard let authentication = user.authentication else { return }
      let credential = FIRGoogleAuthProvider.credential(withIDToken: authentication.idToken,
          accessToken: authentication.accessToken)
      // ...
    }
    
    func signIn(signIn: GIDSignIn!, didDisconnectWithUser user:GIDGoogleUser!,
      withError error: NSError!) {
        // Perform any operations when the user disconnects from app here.
        // ...
    }
    
  6. ログインビューのコントローラが GIDSignInUIDelegate プロトコルを実装することを宣言します。

    Objective-C

    ビュー コントローラのヘッダー ファイルに次の行を追加します。

    @interface MainViewController : UITableViewController<GIDSignInDelegate,
                                                          GIDSignInUIDelegate>
    

    Swift

    ビュー コントローラに次の行を追加します。

    class MainViewController: UITableViewController, GIDSignInDelegate, GIDSignInUIDelegate {
    
  7. ビュー コントローラで、viewDidLoad メソッドをオーバーライドして GIDSignIn オブジェクトの UI デリゲートを設定します。さらに、可能な場合はサイレント ログインするようにします(省略可)。

    Objective-C

    - (void)viewDidLoad {
      [super viewDidLoad];
    
    [GIDSignIn sharedInstance].uiDelegate = self;
    [[GIDSignIn sharedInstance] signIn];
    
      // TODO(developer) Configure the sign-in button look/feel
      // ...
    }
    

    Swift

    override func viewDidLoad() {
      super.viewDidLoad()
    
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().signIn()
    
      // TODO(developer) Configure the sign-in button look/feel
      // ...
    }
    
  8. GIDSignInButton をストーリーボードまたは XIB ファイルに追加するか、プログラムによって初期化します。このボタンをストーリーボードまたは XIB ファイルに追加するには、ビューを追加して、そのカスタムクラスを GIDSignInButton に設定します。
  9. 省略可: このボタンをカスタマイズする方法は次のとおりです。

    Objective-C

    1. ビュー コントローラのヘッダー ファイルで、ログインボタンをプロパティとして宣言します。
      @property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton;
    2. 宣言した signInButton プロパティにボタンを接続します。
    3. GIDSignInButton オブジェクトのプロパティを設定してボタンをカスタマイズします。

    Swift

    1. ビュー コントローラで、ログインボタンをプロパティとして宣言します。
      @IBOutlet weak var signInButton: GIDSignInButton!
    2. 宣言した signInButton プロパティにボタンを接続します。
    3. GIDSignInButton オブジェクトのプロパティを設定してボタンをカスタマイズします。

3. Firebase で認証する

signIn:didSignInForUser:withError: メソッドで、Google ID トークンと Google アクセス トークンを GIDAuthentication オブジェクトから取得して、Firebase 認証情報と交換します。

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];
    // ...
  } else
    // ...
}

Swift

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
  if let error = error {
    // ...
    return
  }

  guard let authentication = user.authentication else { return }
  let credential = FIRGoogleAuthProvider.credential(withIDToken: authentication.idToken,
      accessToken: authentication.accessToken)
  // ...
}

最後に、認証情報を使用して Firebase での認証を行います。

Objective-C

[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRUser *user, NSError *error) {
                            // ...
                              if (error) {
                                // ...
                                return;
                              }

Swift

FIRAuth.auth()?.signIn(with: credential) { (user, error) in
  // ...
    if let error = error {
      // ...
      return
    }

次のステップ

ユーザーが初めてログインすると新しいユーザー アカウントが作成され、ユーザーがログインに使用した認証情報(ユーザー名とパスワードや認証プロバイダ情報)にリンクされます。この新しいアカウントは Firebase プロジェクトの一部として保存され、ユーザーのログイン方法にかかわらず、プロジェクトのすべてのアプリでユーザーを識別するために使用できます。

  • アプリでは、FIRUser オブジェクトからユーザーの基本的なプロフィール情報を取得できます。ユーザーの管理についての記事をご覧ください。

  • Firebase Realtime Database と Firebase Storage のセキュリティ ルールで、ログイン済みユーザーに固有のユーザー ID を auth 変数から取得し、これを使用してユーザーがアクセスできるデータを制御できます。

既存のユーザー アカウントに認証プロバイダの認証情報をリンクすることで、ユーザーが複数の認証プロバイダを使用してアプリにログインできるようになります。

ユーザーのログアウトを行うには signOut: を呼び出します。

Objective-C

    NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

Swift

    let firebaseAuth = FIRAuth.auth()
do {
  try firebaseAuth?.signOut()
} catch let signOutError as NSError {
  print ("Error signing out: %@", signOutError)
}
  

さまざまな認証エラーに対応できるようにエラー処理コードを追加することもできます。エラーの処理についての記事をご覧ください。

フィードバックを送信...