Firebase Flutter Google Calandar API IT

【IT】FlutterでFirebaseとGoogle Calendar APIを使ってイベントを登録する

flutter_firebase_google_calendar_api

今回はFlutterでFirebaseとGoogle Calendar APIを使ってGoogle Calendarにイベントを登録する方法について投稿します。

Android Studio プロジェクト作成

Android StudiodでFlutterのプロジェクトを作成します。

なお、Flutterのインストール方法については、以下を参照してください。

Android Studioを起動して「File」-> 「New」->「New Flutter Project...」を選択します。

「Flutter Application」を選択し、「Next」ボタンを押下します。

「Project name」「Flutter SDK path」「Ploject location」「Discription」それぞれ値を設定します。設定後に「Next」ボタンを押下します。

「Package name」を設定します。設定後に「Finish」ボタンを押下します。これでFlutterのプロジェクト作成は完了です。

Firebase設定

Firebaseを設定します。以下のURLからFirebaseを設定します。

https://firebase.google.com/?hl=ja

Firebaseのトップ画面から「使ってみる」を押下します。

「プロジェクトを追加」を押下します。

「プロジェクト名」を入力し、「続行」ボタンを押下します。プロジェクトの作成が完了するまで待ちます。

「Authentication」を選択します。

「始める」を選択します。

「Google」を選択します。

トグルボタンを押下して「有効にする」を選択します。

「プロジェクトの公開名」「プロジェクトのサポートメール」を入力します。

「ステータス」が有効になっていることを確認します。

Androidで設定します。

「Android パッケージ名」、「アプリのニックネーム」、「デバッグ用の署名証明書 SHA-1(省略可)」を入力します。

「Android パッケージ名」はAndroid Studio から設定します。「android」->「app」の「build.gradle」の「applicationId」を設定します。「アプリのニックネーム」は任意の名称を設定します。

「デバッグ用の署名証明書 SHA-1(省略可)」は以下のコマンドを使います。

    
keytool -exportcert -alias androiddebugkey -keystore "%USERPROFILE%\.android\debug.keystore" -list -v
    

証明書のフィンガプリントを設定します。設定後「アプリを登録」ボタンを押下します。

「google-servies.jsonをダウンロード」を押下してjsonファイルを配置します。配置先は「Andoroid」->「app」配下に配置します。配置後「次へ」ボタンを押下します。

google-services.json ファイルの読み込み設定を行います。

「android]->bild.gradleファイルを修正します。設定後「次へ」ボタンを押下します。

「コンソールに進む」ボタンを押下します。

Google Calendar API設定

Google Calendar APIの設定を行います。

Firebaseで設定したプロジェクトを選択します。

「+APIとサービス有効化」を押下します。

Google Calendar API」を選択します。

「有効にする」ボタンを押下する。

プラグインインストール

pubspec.ymlファイルにインストールするパッケージ名を記入します。

https://pub.dev/packages/firebase_auth

https://pub.dev/packages/firebase_core

https://pub.dev/packages/googleapis

https://pub.dev/packages/google_sign_in

  
firebase_auth: ^0.20.0+1
firebase_core: ^0.7.0
googleapis: ^0.56.1
google_sign_in: ^4.5.9
  

main.dart実装

インポート処理を実装します。

  
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:googleapis/calendar/v3.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:http/http.dart';
import 'package:http/io_client.dart' show IOClient;
import 'package:http/src/io_streamed_response.dart';
  

メインメソッドは以下の通りです。

  
/// メインメソッド
///  Firebaseの初期化を行うため非同期を利用する
Future&glt;void< main() async {
  // main関数で非同期する場合は以下の記述が必要
  WidgetsFlutterBinding.ensureInitialized();
  // firebase初期化
  await Firebase.initializeApp();
  
  runApp(MyApp());
}
  

Firebase.initializeAppを利用する際は非同期処理を使います。main関数で非同期処理を行う場合WidgetsFlutterBinding.ensureInitialized();を記載します。

StatelessWidgetでMyAppクラスを実装します。

  
/// MyAppクラス ステートレスウィジット
class MyApp extends StatelessWidget {
  /// 開始終了連絡カレンダー設定
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '開始終了連絡カレンダー',
      home: MyHomePage(title: '開始終了連絡カレンダーページ'),
    );
  }
}
  

StatelessWidgetでMyAppクラスを実装します。

  
/// MyHomePageクラス ステートフルウィジット
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}
  
  
/// MyHomePageステートクラス
class _MyHomePageState extends State<MyHomePage> {
  /// ウィジット ビルド メソッド
  @override
  Widget build(BuildContext context) {
    // FirebaseAuthインスタンスを作成する
    final _auth = FirebaseAuth.instance;

    final _googleSignIn = GoogleSignIn(scopes: [
      'https://www.googleapis.com/auth/contacts.readonly',
      'https://www.googleapis.com/auth/calendar',
    ]);

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          // 中央寄せ
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
                child: const Text('サインイン'),
                onPressed: () async {
                  await signInWithGoogle(_googleSignIn);
                }),
            Text(
              '開始と終了ボタンを押下してカレンダーに登録します。',
            ),
            Container(
              child: Row(
                // 中央寄せ
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  RaisedButton(
                      child: const Text('開始'),
                      onPressed: () async {
                        await _onEventButton(_googleSignIn, 0);
                      }),
                  RaisedButton(
                      child: const Text('終了'),
                      onPressed: () async {
                        await _onEventButton(_googleSignIn, 1);
                      }),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// google Sign In
  Future<UserCredential> signInWithGoogle(GoogleSignIn _googleSignIn) async {
    try {
      GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn();
      print('---------- サインイン>');
      print(googleSignInAccount.toString());

      // リクエストから、認証情報を取得
      GoogleSignInAuthentication googleAuth =
          await googleSignInAccount.authentication;
      print('---------- 認証情報取得>');
      print(googleAuth.toString());
      print(googleAuth.accessToken);
      print(googleAuth.idToken);

      // クレデンシャル作成
      final credential = GoogleAuthProvider.credential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );
      print('---------- クレデンシャル作成');

      // Firebaseにログイン
      FirebaseAuth.instance.signInWithCredential(credential);
    } catch (e) {
      print(e);
    }
  }

  /// event登録ボタン
  Future<UserCredential> _onEventButton(
      GoogleSignIn _googleSignIn, int type) async {
    try {
      GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn();
      print('---------- サインイン>');
      print(googleSignInAccount.toString());

      // リクエストから、認証情報を取得
      var client = GoogleHttpClient(await googleSignInAccount.authHeaders);
      var calendar = CalendarApi(client);

      String calendarId = "primary";
      Event event = Event();

      switch (type) {
        case 0:
          event.summary = "開始";
          break;
        case 1:
          event.summary = "終了";
          break;
        default:
          break;
      }

      EventDateTime start = EventDateTime();
      start.dateTime = DateTime.now();
      start.timeZone = "GMT+09:00";
      event.start = start;

      EventDateTime end = EventDateTime();
      end.timeZone = "GMT+09:00";
      end.dateTime = DateTime.now().add(Duration(days: 1));
      event.end = end;

      calendar.events.insert(event, calendarId).then((value) {
        if (value.status == "confirmed") {
          print('イベントの追加に成功');
        } else {
          print("イベントの追加失敗");
        }
      });
    } catch (e) {
      print('エラー $e');
    }
  }
}
  

Google Sign Inを使って認証を行います。authenticationでFirebaseの認証情報を取得し、GoogleAuthProvider.credentialを作成して FirebaseAuth.instance.signInWithCredential(credential)でFirebaseにログインします。

event登録ボタンも同様にGoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn()にログインしGoogle Calendar APIのCalendarクラスを生成しイベントを登録します。

  
/// Googleの認証をStream型式で行うHTTLクライアント
class GoogleHttpClient extends IOClient {
  Map<String, String> _headers;

  GoogleHttpClient(this._headers) : super();

  @override
  Future<IOStreamedResponse> send(BaseRequest request) =>
      super.send(request..headers.addAll(_headers));

  @override
  Future<Response> head(Object url, {Map<String, String> headers}) =>
      super.head(url, headers: headers..addAll(_headers));
}

  

Google Calendar APIの通信はStream型式で行います。

動作確認

Debugを使って動作を確認します。動作確認は、実機、または、エミュレータを使って確認します。

開始ボタン、終了ボタンを押下してGoogle Calendarにイベントを登録します。

Google Calendarのアプリを開くとイベントが登録されていることが確認できます。

まとめ

まだ未熟で間違っている箇所もありますが、なんとか実装できたと思います。

今回開始イベントの終了時間は、開始時間の+1日と設定しているので翌日になっています。

また、終了イベントは開始イベントを上書きしていないため、カレンダー上は2つのイベントが表示されるようになっています。

今後は開始時間の上書を実施します。

コメント

0 件のコメント:

コメントを投稿

コメントをお待ちしています。