はじめに
※この記事は、以下の記事の続編です。
【Mac不要】iOSとAndroidのFlutterアプリから利用者のGoogle Photosにアクセスする手順 - Codemagic編 (前編)
この記事ではその後、Flutterアプリから利用者のGoogle Photoにアクセスするための手順を説明します。
ただし、具体的な実装方法は Build a Photo Sharing app with Google Photos and Flutter - Codelabs で公開されているので、ここでは主に「Googleアカウント(Firebase認証)からの"Build a Photo Sharing app with Google Photos"」の適用手順を説明します。
では早速始めましょう。
前提
この記事は、以下に当てはまる人向けの iOS/Android 対応アプリにGoogle Sign-in APIを組み込む手順を紹介します。
- 開発機はWindowsだ
- Macを持っていない
- Flutterで開発したい
- Apple Developer Programに既に登録している。
開発環境の前提
以下の4本の記事の手順に沿ってFlutterアプリの作成を進めてください。
- 【Mac不要】開発中のFlutter製アプリをiOSとAndroidに実機配備する手順 - Codemagic編
- 【Mac不要】FlutterアプリにFirebase SDKを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編
- 【Mac不要】FlutterアプリにFirebase Crashlyticsを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編
- 【Mac不要】iOSとAndroidのFlutterアプリから利用者のGoogle Photosにアクセスする手順 - Codemagic編 (前編)
ソースコードの公開
この記事の手順で作成したソースコードはGithubで公開しています。併せてご参照ください。
https://github.com/atsuteru/flutter_firebase_0507/tree/Qiita-GooglePhoto-v1.2
本文
APIのインタフェースを準備する
Google Photos APIを利用して新規アルバムを作成する場合、次のAPIを利用します。
Method: albums.create - Google Photos APIs
そこには、Requestとして必要なJsonデータの形式が記述されていますね。このJsonを組み立てるための型を準備しましょう。
その型は、Codelabsでサンプルを公開してくれているので、それをそのまま利用しちゃいましょう。
次の4つのソースコードをダウンロードしてください。
Github: googlecodelabs/photos-sharing/lib/
* lib/photos_library_api/album.dart
* lib/photos_library_api/album.g.dart
* lib/photos_library_api/create_album_request.dart
* lib/photos_library_api/create_album_request.g.dart
これを、自身のアプリの lib/photos_library_api の下に取り込みます。
取り込んだ後、create_album_request.dart
のimport宣言の一部を書き換えてください。
//import 'package:sharing_codelab/photos_library_api/album.dart';
import 'album.dart';
APIの認証ヘッダを準備する
Google Photos APIを利用するためには、送信するHTTPリクエストに認証ヘッダを加える必要があります。
認証ヘッダは、Googleアカウントにサインインした情報から得ることができます。
サインイン処理を、以下のように修正しましょう。
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
FirebaseUser _currentUser;
//...(追加ココカラ)...
Future<Map<String, String>> _authHeaders;
//...(追加ココマデ)...
Future<bool> _handleSignIn(GoogleSignInAccount googleSignInAccount) async {
if (googleSignInAccount == null) {
return false;
}
final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken,
);
final AuthResult authResult = await _auth.signInWithCredential(credential);
final FirebaseUser user = authResult.user;
if (user.isAnonymous) {
return false;
}
if (await user.getIdToken() == null) {
return false;
}
final FirebaseUser currentUser = await _auth.currentUser();
if (user.uid != currentUser.uid) {
return false;
}
setState(() {
_currentUser = currentUser;
//...(追加ココカラ)...
_authHeaders = googleSignInAccount.authHeaders;
//...(追加ココマデ)...
});
return true;
}
}
新規アルバムを作成するためのAPI呼び出しをコーディングする
新規アルバムを作成するためのAPI呼び出しの方法は、Codelabsの手順 (5) Create an albumで紹介されています。
それを参考にコーディングすると、例えば「Make Album
ボタンが押された際に新規アルバムを作成するメソッド」は以下のように書くことができます。
http.post
の引数headers
に注目。準備しておいたAPIの認証ヘッダ_authHeaders
が指定されていますね。
//...(中略)...
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'photos_library_api/album.dart';
import 'photos_library_api/create_album_request.dart';
//...(中略)...
class _MyHomePageState extends State<MyHomePage> {
//...(中略)...
Future<void> _handleMakeAlbum() async {
return http
.post(
'https://photoslibrary.googleapis.com/v1/albums',
body: jsonEncode(CreateAlbumRequest.fromTitle("New Album")),
headers: await _authHeaders,
)
.then(
(Response response) {
if (response.statusCode != 200) {
Crashlytics.instance.log('album create error. reasonPhrase=${response.reasonPhrase}');
}
var album = Album.fromJson(jsonDecode(response.body));
Crashlytics.instance.log('album created. albumId=${album.id}.');
},
);
}
なお、ここまでのコーディング内容では、次のライブラリが利用されています。
これらを pubspec.yamlに追加しましょう。
dependencies:
flutter:
sdk: flutter
firebase_core: ^0.4.4+3
firebase_crashlytics: ^0.1.3+3
firebase_auth: ^0.16.0
google_sign_in: ^4.4.6
json_annotation: ^3.0.1
http: ^0.12.1
追加したら、packages get
の実行を忘れずに。
ここまでで、ビルドが通るようになります。
新規アルバムを作成するボタンを配置する
サインイン後の画面に、新規アルバムを作成するボタンMake Album
を追加しましょう。
class _MyHomePageState extends State<MyHomePage> {
//...(中略)...
Widget _buildGoogleSignInBody() {
if (_currentUser != null) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Card(
color: Colors.lightBlueAccent,
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
_currentUser.photoUrl,
),
radius: 30,
backgroundColor: Colors.transparent,
),
title: Text(_currentUser.displayName ?? ''),
subtitle: Text(_currentUser.email ?? ''),
),
),
const Text("Signed in successfully."),
RaisedButton(
child: const Text('SIGN OUT'),
onPressed: _handleSignOut,
),
//...(追加ココカラ)...
RaisedButton(
child: const Text('Make album'),
onPressed: _handleMakeAlbum,
),
//...(追加ココマデ)...
],
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Text("You are not currently signed in."),
RaisedButton(
child: const Text('SIGN IN'),
onPressed: () async{
if (await _handleSignIn(await _googleSignIn.signIn())) {
_handleGetContact();
}
}
),
],
);
}
}
以上でコーディングは完了です。
アプリを実行し、任意のGoogleアカウントでサインインすると、次のようにMake Album
ボタンが表示されます。
それをタップし、サインインしたGoogleアカウントのPhotosの「アルバム」のページを表示すると・・・
New Album
という名の空のアルバムが作成されていますね!
ちなみに、さらにMake Album
ボタンをタップすると、New Album
という名の空のアルバムが増えていきます。
同じタイトルが付けられたアルバムですが、内部的にはAlbumIdが異なっているので、複数作られるというからくりです。
外部サービスへのアウトプットができると、いよいよアプリを作ってる!という感じになりますねっ(空のアルバム作っただけ・・・^^;
さて以上で、この記事における手順は終了ですが、この続きはCodeLabsの記事 Build a Photo Sharing app with Google Photos and Flutter - Codelabs を参考に進めることができます。
写真のアップロードとアルバムへの追加方法などが学習できるので、ぜひやってみてください。
さいごに
ここまでの連載?で、Codemagicを利用してビルドしたり、GoogleやFirebaseとの連携を手作業で設定したりすれば、Macがない環境でもFlutterでクロスプラットフォームアプリの開発ができることを紹介しました。
Windowsはある、iPhoneもある。
でもMacやAndroidは持っていない。
そんな私と同じ環境の方も、ご自身のiPhoneで動作するアプリ開発を!
ここまでの連載が、そんなチャレンジのお役に立てば、幸いです。
ありがとうございました。