【Flutter】FirebaseにREST APIで接続する(全OS対応)

【Flutter】FirebaseにREST APIで接続する(全OS対応)アイキャッチ 技術メモ

サーバが必要なアプリで大活躍のFirebaseですが、今のところ、Google公式のFirebaseパッケージでは、Windowsは対応されていません。

そこで、本記事ではREST API(パッケージ使用)を使って「iOS・Android・MacOS・Windows・Linux」すべてのOSに対応した方法でFirebaseに接続してみます。(Webも含む)

本記事で実現すること
  • Firebase REST APIを使って、Authenticationの新規登録とログイン
本記事では紹介しないこと
  • 新規登録・ログイン機能におけるセキュリティを考慮した実装(パスワードの文字数チェック・回数制限など…)
  • Firebase REST APIを使って、Firestore Database / Realtime Databaseと接続すること(時間 or 要望があったら追加記事を書きます)

注意事項(必ず目を通してください)

本記事では、Firebase Authenticationをメールアドレス・パスワードで認証しています。ただ、これはRFC 6749, 4.3. Resource Owner Password Credentials Grant で定義されているフローで、このフローの使用は「他の認可フローがどうしても使用できない時のみ」に限るべきです。つまり、Firebaseにおいて、メールアドレス・パスワードによる認証は避けるべきです。

なので、本記事は「こんなこともできるんだねー」くらいの気持ちで見ていただけると助かります。

なぜ、使ってはいけないフローか?という点に関してましては、以下の記事をご覧ください。

この記事で紹介するアプリの画面

  • Homeページ
  • 新規登録 / ログインページ
  • アカウント情報ページ(紹介はしない)

Homeページ画面

Firebase-REST-API-sample-Home

新規登録 / ログイン ページ画面

(おまけ)アカウント情報ページ画面

Firebase-REST-API-sample-AccountInfo

では、手順を紹介していきます。

Firebase プロジェクトの設定をする

やることは以下の3つ。1つ目の説明は省略します。

やること
  1. Firebase プロジェクトを作成する
  2. Authenticationの「メール/パスワード」認証を有効にする
  3. ウェブAPIキーをメモする

2. Authenticationの「メール/パスワード」認証を有効にする

Firebaseプロジェクトのトップページから、Authentication>Sign-in method>メール / パスワードより、メール / パスワードによる認証を有効にしておきます。

Firebase Authenticationのメール・パスワード認証を有効にする

3. ウェブAPIキーをメモする

Firebase REST APIを使用する際に、APIキーが必要なので、メモっておきます。

Firebaseプロジェクトのトップページから、歯車マーク>プロジェクトを設定>全般より、ウェブAPIキーをメモしておきます。

FirebaseウェブAPIキーの取得

ここから、Flutter側の実装です。

必要なパッケージを導入する

以下のパッケージをpubspec.yamlファイルに記述して、Pub getする。

dependencies:
  firebase_auth_rest: ^2.0.0
  firebase_database_rest: ^1.0.2 # ★必須ではない。Databaseと接続する際に必要。
  flutter_dotenv: ^3.1.0 # ★必須ではない。本記事では、APIKEYを.envファイルから取得するため必要。

.envファイルからAPIキーを取得する部分を実装する

ウェブAPIキーは、外部に公開してはいけない秘密情報、かつ、環境(Firebaseプロジェクト毎)により異なる値なので、.envファイルから読み取るように実装しました。

やること
  1. .envファイルを作成してAPIキーを記載する
  2. main()メソッドを書き換える
  3. env[‘APIKEY’]で取得する

1. .envファイルを作成してAPIキーを記載する

.envファイルをプロジェクトのルートディレクトリに作成して、中身を以下のように記載します。

APIKEY='ここにAPIキーを書いておく'

2. main()メソッドを書き換える

以下のように記載して、.envファイルを読み込んでおきます。

Future<void> main() async {
  await DotEnv.load(fileName: '.env'); // <-追加
  runApp(MyApp());
}

3. env[‘APIKEY’]で取得する

以下のようにすれば、.envファイルに書いたものを簡単に取得できます。必要なところで読み込むだけでOK。本記事では、FirebaseAuthインスタンスを生成する直前で読み込んでいます。

final apiKey = env['APIKEY'];

新規登録 / ログイン機能を実装する

メールアドレスとパスワードを入力してもらい、ボタンを押すことで新規登録(ログイン)ができる機能を実装します。

StatefulWidgetで実装していきます。

TextFieldとボタンを用意する

まず、メールアドレス・パスワードを入力してもらうTextFieldと、新規登録ボタンを用意します。

class SignUpPage extends StatefulWidget {
  @override
  _SignUpPageState createState() => _SignUpPageState();
}

class _SignUpPageState extends State<SignUpPage> {
  var emailTextEditingController = TextEditingController();
  var passwordTextEditingController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('新規登録ページ'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              margin: EdgeInsets.all(20),
              child: TextField(
                controller: emailTextEditingController,
                maxLength: 30,
                decoration: const InputDecoration(
                  icon: Icon(Icons.mail),
                  hintText: 'メールアドレスを入力してください',
                  labelText: 'メールアドレス *',
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.all(20),
              child: TextField(
                controller: passwordTextEditingController,
                maxLength: 15,
                obscureText: true,
                decoration: const InputDecoration(
                  icon: Icon(Icons.lock),
                  hintText: 'パスワードを入力してください',
                  labelText: 'パスワード *',
                ),
              ),
            ),
            ElevatedButton(
              onPressed: () => SignUpWithPassword(),
              child: Text('登録する'),
            )
          ],
        ),
      ),
    );
  }
}

ボタンを押したときに、新規登録(ログイン)する

上記では、ElevatedButtonをタップしたときにSignUpWithPassword()メソッドを呼ぶようにしました。その中身を実装していきます。

※Client()を使うために、.dartファイル冒頭に「import ‘package:http/http.dart’;」をお忘れなく。

  /// E-mail/Passで新規登録
  Future<void> SignUpWithPassword() async {
    final client = Client();
    final apiKey = env['APIKEY'];
    try {
      final fbAuth = FirebaseAuth(client, apiKey, 'ja-JP');
      final account = await fbAuth.signUpWithPassword(emailTextEditingController.text, passwordTextEditingController.text);
      final accountInfo = await account.getDetails();

      await Navigator.popAndPushNamed(context, '/account_info', arguments: accountInfo);

    } catch (e) {
      print(e);
    } finally {
      print('Clientをクローズします。');
      client.close();
    }
  }

fbAuth.signUpWithPassword()で新規登録を行っています。正常完了した場合は、print(accountInfo)でメールアドレスなどがコンソールに表示されますが、例外が起きた場合は、catch句のprint(e)でエラー内容が見られます。

また、ログインの実装方法は新規登録とほとんど同じで、fbAuth.signUpWithPassword()ではなく、fbAuth.signInWithPassword()を使用するだけです。

(おまけ)アカウント情報ページ

ソースコードはGitHubを参照してほしいが、ログイン成功後に受け取ったアカウント情報をアカウント情報ページへ渡して見ました。

Firebase-REST-API-sample-AccountInfo

全ソースコードはこちら

おわりに

セキュリティ的に色々考えるべきことは、まだまだ多くありそうだが、同じソースコードで全OS+Webまで対応できるのは効率が良くおもしろい。

【MacOSの場合】
ネットワーク要求の権限が必要なので、『Xxx.entitlements』ファイルを編集する必要があります。詳しくは、以下の記事を参考にしてください。

【免責事項】
本記事を参考に作成したアプリに関しまして、一切の責任は負いませんこと、ご了承願います。

コメント

タイトルとURLをコピーしました