【IT】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つのイベントが表示されるようになっています。
今後は開始時間の上書を実施します。
ript>alert(123456)
返信削除