📱

Flutter Apple Sign In

2023/07/06に公開

以前書いた記事が詳しく書けてないので作り直した!

FlutterでApple Sign Inを実装するのをやってみようと思います。
必要なもの

  1. apple developerアカウント
  2. iPhoneの実機

プロジェクトを作る

メソッドを呼び出して、実行するだけなので、StatefulWidgetでもボタンの中で、メソッドを呼び出せば実行できます。
今回は、flutter_hooksでやってます。

カスタムHookで作成したメソッド

hook/auth_hooks.dart
// flutter_hooksで、Apple Sign Inをスルメソッドを実装する
import 'package:custom_hook_api/main.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';

// カスタムHookで作成したメソッド(自作したメソッドってことですね)
Future<UserCredential> appleSignInHook(BuildContext context) async {
  print('AppSignInを実行');
  // generateNonceは、sign_in_with_appleパッケージの中にあるメソッド
  final rawNonce = generateNonce();

  // ここで、Apple Sign Inの認証画面が表示される
  final appleCredential = await SignInWithApple.getAppleIDCredential(
    scopes: [
      AppleIDAuthorizationScopes.email,
      AppleIDAuthorizationScopes.fullName,
    ],
  );
  print(appleCredential);
  // ここで、Firebaseの認証画面が表示される
  final oauthCredential = OAuthProvider("apple.com").credential(
    idToken: appleCredential.identityToken,
    rawNonce: rawNonce,
  );
  // ここに画面遷移をするコードを書く!
  if (context.mounted) {
    Navigator.of(context).pushAndRemoveUntil(
        MaterialPageRoute(builder: (context) => const HomePage()),
        (route) => false);
  }
  print(appleCredential);
  // ここで、Firebaseの認証が完了する
  return await FirebaseAuth.instance.signInWithCredential(oauthCredential);
}

Apple Sign Inと、ログイン後のページを書いたファイル

main.dart
import 'package:custom_hook_api/firebase_options.dart';
import 'package:custom_hook_api/hook/auth_hook.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:sign_in_button/sign_in_button.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const MyApp());
}

class MyApp extends HookWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'API Data Example',
      home: AppleSignInDemo(),
    );
  }
}

// Apple Sign Inするページ
class AppleSignInDemo extends HookWidget {
  const AppleSignInDemo({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.black,
        title: const Text('Apple Sign In Demo'),
      ),
      body: Center(
        child: Container(
          width: 200,
          height: 30,
          child: SignInButton(
            Buttons.apple,
            onPressed: () async {
              try {
                // ここで、カスタムHookで作成したメソッドを呼び出す
                await appleSignInHook(context);
              } catch (e) {
                // エラー処理
                if (e is SignInWithAppleAuthorizationException &&
                    e.code == AuthorizationErrorCode.canceled) {
                  print('User canceled sign in process');
                  // Here, show some message to the user or handle the cancellation in a way that fits your app
                } else {
                  print(e);
                }
              }
            },
          ),
        ),
      ),
    );
  }
}

// Apple Sign Inしたページ
class HomePage extends HookWidget {
  const HomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    final auth = FirebaseAuth.instance;
    return Scaffold(
      appBar: AppBar(
        title: const Text('Apple Sign Inしました!'),
      ),
      body: Center(
          child: ElevatedButton(
        child: const Text('Sign Out'),
        onPressed: () async {
          // ログアウトする
          await auth.signOut();
          if (context.mounted) {
            Navigator.of(context).pushAndRemoveUntil(
                MaterialPageRoute(
                    builder: (context) => const AppleSignInDemo()),
                (route) => false);
          }
        },
      )),
    );
  }
}

🎁パッケージを追加する

ボタンのデザインが用意されているライブラリ。使うときは幅と高さの設定を忘れずに!
https://pub.dev/packages/sign_in_button
AppleSignInに必要なライブラリ
https://pub.dev/packages/sign_in_with_apple
firebaseに必要なライブラリ
https://pub.dev/packages/firebase_core
https://pub.dev/packages/firebase_auth
flutter_hooksを使うので、追加
https://pub.dev/packages/flutter_hooks

x-codeの設定をする

Apple Developerのアカウントを持っていないとできません🙅
ですので、やってみたい人は、作ってください。年間1万円以上取られます😇

Teamのところに、自分のアカウントを設定します。チーム開発の時は、チームのApple Developerのアカウントを設定します。
Bundle Identifierは、コピーしておいて、Apple Developerのサイトで、設定するときに使用します。

com.exampleのままだと、できないので注意!



Apple Developerの設定をする




画面左から、Identifiersを選択して、iOSアプリの設定をする

画面右の青いボタンを押す

Appが選択された状態で、画面右の青いボタンを押す

Bundle Identifierの設定をする

Sign In With Appleにチェックをつける

登録されていればOK

Firebaseの設定をする

プロジェクトを作成した状態で、Firebase Auenticationで、Apple Sign Inの設定をします。



📸スクリーンショット

認証をするときは、iPhoneの種類によって、指紋認証と顔認証に分かれます。iPhone10でやったときは、パスコードを入力しないと、うまくいかなかったです?



まとめ

以前書いた記事とロジックは同じなので、そちらも参考にしてみてください。
https://zenn.dev/flutteruniv_dev/articles/b92482ca1fd693

Discussion