GoogleのFlutterとFirebaseでアプリ開発

`Google`が提供するオープンソース型のモバイルUIフレームワーク`Flutter`とバックエンドサービスとしてアプリ開発プラットフォームの`Firebase`を組み合わせれば、`SNS`を使ったアカウント作成・チャット・プッシュ通知などの機能が簡単に実装できアプリ開発が楽になります。`Flutter`は無料で提供されていますが、`Firebase`はサーバーサイドを担うので無料のプランもあるものの、使った分だけの従量制プランが推奨されています。大規模なアプリ開発になれば無料では無理かと。。`Firebase`を`Flutter`に連携させるのに[こちらのドキュメント](https://firebase.google.com/docs/flutter/setup?hl=ja&platform=ios
)を参考に構築すると良いでしょう。
![スクリーンショット 2022-09-27 14.20.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/bfc51ec8-3384-4a09-7da7-5912e9898771.png)
**1.Google アカウントで Firebase にログイン**
**2.Firebase CLI をインストール**
**3.FlutterFire CLIを使ってFlutter アプリを Firebase に紐付け**
**4.Flutter プロジェクトでFirebase の初期化**
**5.Flutter アプリの Firebase 構成を最新にする**
**6.main.dart ファイルで、Firebase Core プラグインをインポート**
**7.同じくmain.dart ファイルでFirebase を初期化**
**8.Flutter アプリケーションを再ビルド**
**9.Firebase Flutter プラグインの追加**

の流れで取り込みます。今回は使用頻度が高いプラグインをまとめてみました。

# [firebase_core](https://pub.dev/packages/firebase_core)
**複数の Firebase アプリへの接続を可能にする Firebase Core API を使用するためのプラグイン**
```dart
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
　　　　  options: DefaultFirebaseOptions.currentPlatform,
  )；
  runApp(const MyApp());
}
```
DefaultFirebaseOptions オブジェクトを使用して Firebase を初期化。`android/app/build.gradle`のminSdkVersionを21以上、`ios/podfile`のplatformを10以上に設定。
```dart
final funcs = FirebaseFunctions.instanceFor(
    app: Firebase.app(), region: 'asia-northeast1');

Future<dynamic> call(String name, dynamic params) async {
  return (await funcs.httpsCallable(name).call(params)).data;
}
```
Firebase Flutter Functionsのリージョン(関数のロケーション)を東京に指定しhttpsCallable関数で呼び出し、戻り値を取り出す。


# [firebase_auth](https://pub.dev/packages/firebase_auth)
**Authenticationはメールアドレスや電話番号、Googleアカウントを使った認証が安全に使用することが可能です。**
```dart
import 'package:firebase_auth/firebase_auth.dart' show FirebaseAuth;

Future<User?> fetchUser() async {
  final firebaseUser = FirebaseAuth.instance.currentUser;
  if (firebaseUser == null) return null;

  final doc = (await users.doc(firebaseUser.uid).get()).data()!;

  return doc2User(firebaseUser.uid, doc);
}
```
`provider`から値を引っ張ってくると状態管理ができないので`firebaseUser`を定義してあります。

```dart
await FirebaseAuth.instance.signInAnonymously();
```
で、ログインしたい場所を指定。

```dart
await auth.FirebaseAuth.instance.signOut();
```
`auth`で認証したアカウントをログアウトする。


# [firebase_messaging](https://pub.dev/packages/firebase_messaging)
**Cloud Messagingはメッセージを無料で送信することができます。最大 4,000 バイトのペイロードをクライアント アプリに転送できます。プッシュ通知で使われるのが多いでしょう。**
```dart
FirebaseMessaging.instance.requestPermission()
```
通知を受信する権限を要求。
```dart
await FirebaseMessaging.instance.getToken();
```
登録しているトークンを取得。

# [firebase_storage](https://pub.dev/packages/firebase_storage)
**Cloud Storageは、画像や動画などのユーザー生成コンテンツをアップロードして共有できデータをGoogleCloudStorageバケットに保存することができます。**
```dart
import 'package:firebase_storage/firebase_storage.dart';

Future<String?> uploadImage(File file) async {
  try {
    final res = await FirebaseStorage.instance
        .ref("profiles/${currentUid()}.png")
        .putFile(file);
    final url = await res.ref.getDownloadURL();
    await users.doc(currentUid()).update({
      'imageUrl': url,
    });
    return url;
  } on FirebaseException catch (e) {
    print(e);
　　　　　　　　// FirebaseExceptionを初期化
  }
  return null;
}
```
`Cloud Storage`への画像のアップロードは`ref()メソッド`で`iOS`から参照したものを`putFile`で保存します。