FlutterでFacebookログインしてFirebaseでユーザー作成（iOS）

# 必要なもの

- Facebook Developerでアプリ作成
    - appID
    - secret key
- Direbaseでアプリ作成
    - Google-Service.plist
- 利用パッケージ
    - flutter_facebook_login: ^1.2.0
    - firebase_core: ^0.3.0
    - firebase_auth: ^0.8.1

# 事前準備

実装以外の基礎設定はFlutterの仕組みに乗り切れないので、自前でやる必要があります。
`Runner.xcworkspace` を開いて、Google-Service.plistを入れる。

Facebookログインの事前準備である上記IDを等をinfo.plistに追加する。

# 実装

必要なとこだけ抜粋、未だによくbloc patterが理解できていないのでマイページのルートになるコンポーネントにblocをもたせて子に伝搬させていく感じを想定。
こんな実装昔MVVMでもViewModelを子に伝搬させて状態遷移を同期させるのやったことあるんですが、親への依存度が上がるのであんまやりたくないな・・・どうやるんだろう？？

```dart

import 'package:flutter/material.dart';
import 'package:loool/pages/profile/page.dart';
import 'package:loool/blocs/UserBloc.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_facebook_login/flutter_facebook_login.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:loool/models/user.dart';

class MyPagePage extends StatefulWidget {

  final UserBloc userBloc = UserBloc();

  @override
  _MyPagePageState createState() => _MyPagePageState();
}

class _MyPagePageState extends State<MyPagePage> {

  final FirebaseAuth _auth = FirebaseAuth.instance;
  FirebaseUser currentUser = null;

  UserBloc get _userBloc => widget.userBloc;

  String get title => this.currentUser != null ? 'マイページ' : 'ログイン';

  @override
  void initState() {
    super.initState();
    this.updateUserStatus();
  }

  void updateUserStatus() async {
    this.currentUser = await _auth.currentUser();
    if (this.currentUser != null){
      _userBloc.dispatch(UserEvent.login);
    }
  }

  @override
  Widget build(BuildContext context) {

    Future<FirebaseUser> _signInToFirebase(FacebookAccessToken accessToken) async {
      final credential = FacebookAuthProvider.getCredential(accessToken: accessToken.token);
      final FirebaseUser user = await _auth.signInWithCredential(credential);
      return user;
    }

    Future<FacebookLoginResult> _loginToFacebook() async {
      var facebookLogin = FacebookLogin();
      var facebookLoginResult =
      await facebookLogin.logInWithReadPermissions(['email']);
      return facebookLoginResult;
    }

    void login() async{
      FacebookLoginResult facebookLoginResult = await _loginToFacebook();
      switch (facebookLoginResult.status) {
        case FacebookLoginStatus.loggedIn:
          _signInToFirebase(facebookLoginResult.accessToken);
          this.updateUserStatus();
          break;
        default:
          break;
      }
    }

    return Scaffold(
      body: BlocBuilder<UserEvent, bool>(
          bloc: _userBloc,
          builder: (BuildContext context, bool loginState) {
            if (loginState) {
              return ProfilePage(
                  userBloc: _userBloc,
                  user: User(
                    id: this.currentUser.uid,
                    name: this.currentUser.displayName,
                    introduction: "",
                    imageURL: this.currentUser.photoUrl
                  )
              );
            } else {
              debugPrint('is not Logined');
              return Center(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      RaisedButton.icon(
                        color: Colors.white,
                        icon: const Icon(
                            Icons.add, size: 18.0, color: Colors.grey),
                        label: const Text('サインイン', style: TextStyle(
                            fontWeight: FontWeight.bold,
                            color: Colors.grey,
                            fontSize: 13.0)),
                        onPressed: () {
                          login();
                        },
                      ),
                    ],
                  )
              );
            }
        }
      )
    );
  }
}

```