snovaのブログ

主にプログラミングやデジタルコンテンツについて書きます。最近はPython, Flutter, VRに興味があります。

Flutterから利用できるFirebaseサービスをカウンターアプリで実践(In-App Messaging編)

はじめに

Flutterから利用できるFirebaseの機能をカウンターアプリに実装し、内容をまとめたシリーズの第10回目です。

今回はターゲットを絞り込んだメッセージを送信することができるFirebase In-App Messagingについてです。 このサービスはモバイル(iOS, Android)でのみ使用できます。

目次

シリーズの内容

回数 内容 リンク
第0回 準備編 ブログ
第1回 Analytics ブログ
第2回 Firebase Crashlytics ブログ
第3回 Firebase Performance Monitoring ブログ
第4回 Firebase Remote Config ブログ
第5回 Firebase Authentication ブログ
第6回 Cloud Firestore ブログ
第7回 Firebase Realtime Database ブログ
第8回 Cloud Storage for Firebase ブログ
第9回 Firebase Cloud Messaging ブログ
第10回 Firebase In-App Messaging イマココ
第11回 Firebase ML ブログ
第12回 Cloud Functions for Firebase ブログ
第13回 Firebase Hosting ブログ
第14回 Firebaseのその他のサービス ブログ

開発環境

項目 内容
PC Macbook Air(M1)
Flutter 3.0.1
Firebase 11.0.1
FlutterFire 0.2.2+2
デバッグバイス Android 12(APIレベル31), Chrome

準備

準備編が完了出来ているものとします。

snova301.hatenablog.com

導入方法

プロジェクトにfirebase_in_app_messagingを導入するため、pubspec.yamlに追記します。

In-App Messagingはサーバーからのメッセージの取得を1日に1回だけしか行わないため、テストではFirebase installation ID (FID)を使って実験します。

dependencies:
  firebase_in_app_messaging: ^0.6.0+14
  firebase_app_installations: ^0.1.0+14

Flutterでは、firebase_in_app_messagingを読み込むことでIn-App Messagingを使用できます。

import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';

FIDの取得FirebaseInstallationsを使用します。

import 'package:firebase_app_installations/firebase_app_installations.dart';

void getFID() async {
  String id = await FirebaseInstallations.instance.getId();
  print('id : $id');
}

Firebase Consoleから配信テストをします。 準備ができたら、先ほど控えたFIDを入力し、デバイス配信テストを行います。

配信後、デバッグ端末で一度ホーム画面に戻り、再度アプリを開くと、アプリ内メッセージを確認できます。

なお、以下のようなエラーメッセージが発生した場合、Firebase In-App Messaging APIが無効になっていますので、エラー文の通り、Google Cloud Platform Firebase In-App Messaging APIにアクセスし、APIを有効にする必要があります。

PERMISSION_DENIED: Firebase In-App Messaging API has not been used in project *** before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/firebaseinappmessaging.googleapis.com/overview?project=*** then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

コード全文

前回からの変更点です。

  • In-App Messagingを実装

main.dart抜粋

/// Flutter関係のインポート
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'dart:async';

/// Firebase関係のインポート
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:firebase_app_installations/firebase_app_installations.dart';
import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';

/// メイン
void main() async {
  /// クラッシュハンドラ
  runZonedGuarded<Future<void>>(() async {
    /// Firebaseの初期化
    WidgetsFlutterBinding.ensureInitialized();

    /// FCMのバックグランドメッセージを表示
    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

    await Firebase.initializeApp(
      name: isAndroid || isIOS ? 'counterFirebase' : null,
      options: DefaultFirebaseOptions.currentPlatform,
    );

    /// クラッシュハンドラ(Flutterフレームワーク内でスローされたすべてのエラー)
    FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;

    /// runApp w/ Riverpod
    runApp(const ProviderScope(child: MyApp()));
  },

      /// クラッシュハンドラ(Flutterフレームワーク内でキャッチされないエラー)
      (error, stack) =>
          FirebaseCrashlytics.instance.recordError(error, stack, fatal: true));
}

/// MaterialAppの設定
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Counter Firebase',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

/// ホーム画面
class MyHomePage extends ConsumerStatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class MyHomePageState extends ConsumerState<MyHomePage> {
  @override
  void initState() {
    super.initState();

    /// FCMのパーミッション設定
    FirebaseMessagingService().setting();

    /// FCMのトークン表示(テスト用)
    FirebaseMessagingService().fcmGetToken();

    /// Firebase ID取得(テスト用)
    FirebaseInAppMessagingService().getFID();
  }

  @override
  Widget build(BuildContext context) {
...
  }
}


class FirebaseInAppMessagingService {
  void getFID() async {
    String id = await FirebaseInstallations.instance.getId();
    print('id : $id');
  }
}

GitHubのページを貼ります。

github.com

Google Play and the Google Play logo are trademarks of Google LLC.