Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Amplify Flutter を使おうとしたけど微妙な結果に終わった話
Search
hmatsu47
PRO
November 26, 2021
Technology
5.5k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Amplify Flutter を使おうとしたけど微妙な結果に終わった話
JAWS-UG 浜松 AWS 勉強会 2021#11 2021/11/26
hmatsu47
PRO
November 26, 2021
More Decks by hmatsu47
See All by hmatsu47
中小企業に就職して転職せず30年。結果どうなった?
hmatsu47
PRO
0
82
JAWS ミート 2026 の「出し物」のゲームを Kiro と AI-DLC v2 で作った話
hmatsu47
PRO
0
13
ゲームで挑戦!VPC の気持ちになって IPv4/v6 パケットをルーティングしよう!
hmatsu47
PRO
0
28
続・名古屋城とデータセンター
hmatsu47
PRO
0
27
【再演】IPv6 VPC の実装パターンをいくつか
hmatsu47
PRO
0
33
名古屋城とデータセンター
hmatsu47
PRO
0
40
IPv6 に関する話
hmatsu47
PRO
0
29
さいきんの光ファイバーの話
hmatsu47
PRO
0
75
低いほうのレイヤを見てみる話
hmatsu47
PRO
0
34
Other Decks in Technology
See All in Technology
全員がプロダクトへ向き合う組織を持続成長させるために——組織づくりのフライホイールと4象限 / The Flywheel Model and Four Quadrants for Organizational Design
hiro_torii
4
980
2026_devsumi_ozono.pdf
o3
3
410
ASTを使って影響範囲を特定する
nealle
0
170
AIで仕事のやり方を変える
matsu7874
3
1.1k
2026/09/10 Spring Bootから Jakarta EE/MicroProfileへの移行
megascus
0
340
Adaptive Warehouse を今すぐ導入すべき理由と迷ったときの判断基準
__allllllllez__
0
200
作品が生態系になった ─ Mini Tokyo 3D から世界へ
nagix
0
170
『止めない』を設計する — 制約の中で、事業の根幹を支える判断
hiroyaterui
0
270
AI時代、データエンジニアが一番おもろい
genshun9
0
180
ペアプロの価値はコードを書くことだけじゃない
codmoninc
PRO
0
200
生成AIのテナント制御とシャドーMCP対策 | AIを"止めずに"、情報を守る
yukun
0
160
AIに丸投げしないトイル削減 / Eliminating Toil Without Leaving It All to AI
kohbis
4
1.1k
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
57
14k
New Earth Scene 8
popppiees
3
2.5k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
270
We Have a Design System, Now What?
morganepeng
55
8.3k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
The Curious Case for Waylosing
cassininazir
1
500
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
410
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Raft: Consensus for Rubyists
vanstee
141
7.7k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
520
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
280
Transcript
Amplify Flutter を使おうとしたけれど 微妙な結果に終わった話 JAWS-UG 浜松 AWS 勉強会 2021#11 2021/11/26 まつひさ(hmatsu47)
自己紹介 松久裕保(@hmatsu47) https://qiita.com/hmatsu47 名古屋で Web インフラのお守り係をしています (ほかに書くことがなくなったので省略) 2
おことわり • ここに書いた内容は私が実際に試した時点の情報です ◦ 2021/05 〜 2021/10 頃の話です ◦ その後
Amplify CLI のバージョンアップが入っているので、すで に解消されている問題があるかもしれません ◦ 実際、最初に書いた「iOS で DataStore のレコード削除をすると 落ちる」問題はその後解消されていました 3
Flutter を試そうと思ったきっかけ • 以前 Qiita でバズったこのサイト ◦ https://korette.jp/ 4
Flutter を試そうと思ったきっかけ • 以前 Qiita でバズったこのサイト ◦ https://korette.jp/ ◦ サポーターズの一員として大量にクイズ投稿
5
Flutter を試そうと思ったきっかけ • 以前 Qiita でバズったこのサイト ◦ https://korette.jp/ ◦ サポーターズの一員として大量にクイズ投稿
◦ その後、コロナ禍で観光地の状況が一変 ◦ コロナが落ち着いた隙をみながら問題メンテナンスの旅へ 6
Flutter を試そうと思ったきっかけ • 以前 Qiita でバズったこのサイト ◦ https://korette.jp/ ◦ サポーターズの一員として大量にクイズ投稿
◦ その後、コロナ禍で観光地の状況が一変 ◦ コロナが落ち着いた隙をみながら問題メンテナンスの旅へ ◦ 旅のお供として、情報収集・整理のためのアプリが欲しい ◦ 作ることにした 7
余談ですが • ご本人は起業されて・・・ ◦ https://ambirise.jp/ 8
Amplify Flutter を試そうと思った動機 • 普通に考えたら Firebase ◦ Flutter も Google
謹製 9
Amplify Flutter を試そうと思った動機 • 普通に考えたら Firebase ◦ Flutter も Google
謹製 ◦ ありがちで面白くない ◦ どうせなら普段使っている AWS で 10
Amplify Flutter を試してみた • まずはチュートリアルから(英語版) ◦ https://docs.amplify.aws/start/getting-started/installation/q/integration/flutter/ ◦ Android で
DataStore を使った DynamoDB 同期が成功 ◦ iOS ではなぜかレコード削除で落ちる 11
Amplify Flutter を試してみた • まずはチュートリアルから(英語版) ◦ https://docs.amplify.aws/start/getting-started/installation/q/integration/flutter/ ◦ Android で
DataStore を使った DynamoDB 同期が成功 ◦ iOS ではなぜかレコード削除で落ちる ◦ しばらく放置 12
その後 • AWS へのデータ同期は一旦置いて、 ◦ アプリ本体の開発に着手 ◦ https://github.com/hmatsu47/maptool ◦ ローカルへのデータ保存に
SQLite(sqflite)を使用 13
その後 • AWS へのデータ同期は一旦置いて、 ◦ アプリ本体の開発に着手 ◦ https://github.com/hmatsu47/maptool ◦ ローカルへのデータ保存に
SQLite(sqflite)を使用 ◦ ある程度骨格ができたところで、まずは DataStore を導入 ◦ 問題発覚 14
自動生成されたデータモデルがエラーに • 原因は Null Safety ◦ Flutter 2.0 で導入されたもの ▪
この時点ではエラーにはならず ◦ Flutter 2.2 以降で非 Null Safety なデータモデルはエラーに ▪ 仕方なく温かみのある手作業で修正 15
自動生成されたデータモデルがエラーに • 原因は Null Safety ◦ Flutter 2.0 で導入されたもの ▪
この時点ではエラーにはならず ◦ Flutter 2.2 以降で非 Null Safety なデータモデルはエラーに ▪ 仕方なく温かみのある手作業で修正 ◦ ほどなくして Amplify CLI のバージョンアップ通知が ▪ バージョンアップでエラーは解消(ワーニング多くて気持ち悪いけど) 16
自動生成されたデータモデルがエラーに • 原因は Null Safety ◦ Flutter 2.0 で導入されたもの ▪
この時点ではエラーにはならず ◦ Flutter 2.2 以降で非 Null Safety なデータモデルはエラーに ▪ 仕方なく温かみのある手作業で修正 ◦ ほどなくして Amplify CLI のバージョンアップ通知が ▪ バージョンアップでエラーは解消(ワーニング多くて気持ち悪いけど) ◦ そして事件が発生 17
SQLite のテーブルが消失😱 • DataStore のローカルデータ保存 : SQLite を使用 ◦ アプリで実装している
DB は DataStore のローカルストアが 初期化される都度、巻き添えをくらって削除される 18
SQLite のテーブルが消失😱 • DataStore のローカルデータ保存 : SQLite を使用 ◦ アプリで実装している
DB は DataStore のローカルストアが 初期化される都度、巻き添えをくらって削除される ◦ たまたまコピーしてあった SQLite のファイルからローカル DB を復活させた ◦ DataStore 使うなら別のローカル DB を使うこともないか・・・ 19
SQLite のテーブルが消失😱 • DataStore のローカルデータ保存 : SQLite を使用 ◦ アプリで実装している
DB は DataStore のローカルストアが 初期化される都度、巻き添えをくらって削除される ◦ たまたまコピーしてあった SQLite のファイルからローカル DB を復活させた ◦ DataStore 使うなら別のローカル DB を使うこともないか・・・ ◦ しかし 20
DynamoDB に同期されないテーブルがある • 3 つあるテーブルのうち最も単純なものを除いて NG ◦ 試しにテーブルを 1 つにしても
NG 21
DynamoDB に同期されないテーブルがある • 3 つあるテーブルのうち最も単純なものを除いて NG ◦ 試しにテーブルを 1 つにしても
NG ◦ ローカルの SQLite には正しく保存される ◦ AppSync で AWS に送っている形跡はある(ログより) ◦ でもテーブルには同期されない ▪ 「失敗した」ログは出てくれない 22
DynamoDB に同期されないテーブルがある • 3 つあるテーブルのうち最も単純なものを除いて NG ◦ 試しにテーブルを 1 つにしても
NG ◦ ローカルの SQLite には正しく保存される ◦ AppSync で AWS に送っている形跡はある(ログより) ◦ でもテーブルには同期されない ▪ 「失敗した」ログは出てくれない 23
DynamoDB に同期されないテーブルがある • 3 つあるテーブルのうち最も単純なものを除いて NG ◦ 試しにテーブルを 1 つにしても
NG ◦ ローカルの SQLite には正しく保存される ◦ AppSync で AWS に送っている形跡はある(ログより) ◦ でもテーブルには同期されない ▪ 「失敗した」ログは出てくれない 24
DynamoDB に同期されないテーブルがある • 3 つあるテーブルのうち最も単純なものを除いて NG ◦ 試しにテーブルを 1 つにしても
NG ◦ ローカルの SQLite には正しく保存される ◦ AppSync で AWS に送っている形跡はある(ログより) ◦ でもテーブルには同期されない ▪ 「失敗した」ログは出てくれない 25
DynamoDB に同期されないテーブルがある • 3 つあるテーブルのうち最も単純なものを除いて NG ◦ 試しにテーブルを 1 つにしても
NG ◦ ローカルの SQLite には正しく保存される ◦ AppSync で AWS に送っている形跡はある(ログより) ◦ でもテーブルには同期されない ▪ 「失敗した」ログは出てくれない ◦ 諦めた 26
REST API に変えてみた • CLI で amplify add api して
REST を選んで・・・ ◦ API Gateway 経由で Node.js の DynamoDB 保存用 Lambda を 使ってチャレンジ→失敗 ▪ JavaScript 版の Amplify ではうまく行くのに・・・ 27
REST API に変えてみた • CLI で amplify add api して
REST を選んで・・・ ◦ API Gateway 経由で Node.js の DynamoDB 保存用 Lambda を 使ってチャレンジ→失敗 ▪ JavaScript 版の Amplify ではうまく行くのに・・・ ◦ Lambda の環境変数名と Node.js に書かれた環境変数を参照して いる部分の記述がなぜか違う ▪ REGION と TABLE_REGION(なお、直しても動かず) 28
REST API に変えてみた • CLI で amplify add api して
REST を選んで・・・ ◦ API Gateway 経由で Node.js の DynamoDB 保存用 Lambda を 使ってチャレンジ→失敗 ▪ JavaScript 版の Amplify ではうまく行くのに・・・ ◦ Lambda の環境変数名と Node.js に書かれた環境変数を参照して いる部分の記述がなぜか違う ▪ REGION と TABLE_REGION(なお、直しても動かず) ◦ 諦めた 29
結局、 • API Gateway & Lambda Python で回避 ◦ これ↓を参考に
https://business.ntt-east.co.jp/content/cloudsolution/column-try-20.html ◦ コード的には RESTful ではなくなったけどヨシ!! ▪ パスパラメータなし ▪ 全部 POST ◦ クライアント側だけ Amplify Flutter のライブラリを使用 30
結局、 • API Gateway & Lambda Python で回避 ◦ これ↓を参考に
https://business.ntt-east.co.jp/content/cloudsolution/column-try-20.html ◦ コード的には RESTful ではなくなったけどヨシ!! ▪ パスパラメータなし ▪ 全部 POST ◦ クライアント側だけ Amplify Flutter のライブラリを使用 31 // バックアップ情報を登録 Future<bool> backupSet( AmplifyClass amplify, String backupTitle, String describe) async { try { final RestOptions options = RestOptions( path: '/backupsets', body: const Utf8Encoder() .convert(('{"OperationType": "PUT", "Keys": {"items": [' ' {"title": ${jsonEncode(backupTitle)}' ', "describe": ${jsonEncode(describe)}}' ']}}'))); final RestOperation restOperation = amplify.API.post(restOptions: options); await restOperation.response; // ignore: avoid_print print('POST call (/backupsets) succeeded'); return true; } on ApiException catch (e) { // ignore: avoid_print print('POST call (/backupsets) failed: $e'); return false; } }
結局、 • API Gateway & Lambda Python で回避 ◦ これ↓を参考に
https://business.ntt-east.co.jp/content/cloudsolution/column-try-20.html ◦ コード的には RESTful ではなくなったけどヨシ!! ▪ パスパラメータなし ▪ 全部 POST ◦ クライアント側だけ Amplify Flutter のライブラリを使用 32 // バックアップ情報リストを AWS から取得 Future<List<BackupSet>> fetchBackupSets(AmplifyClass amplify) async { final List<BackupSet> resultList = []; try { final RestOptions options = RestOptions( path: '/backupsets', body: const Utf8Encoder().convert(('{"OperationType": "SCAN"}'))); final RestOperation restOperation = amplify.API.post(restOptions: options); final RestResponse response = await restOperation.response; final Map<String, dynamic> body = json.decode(response.body); final List<dynamic> items = body['Items']; for (dynamic item in items) { resultList.add(BackupSet(item['title'] as String, item['describe'])); } resultList.sort((a, b) => b.title.compareTo(a.title)); // ignore: avoid_print print('POST call (/backupsets) succeeded'); } catch (e) { // ignore: avoid_print print('POST call (/backupsets) failed: $e'); } return resultList; }
S3 も・・・ • 個人で使うアプリにわざわざ Cognito を入れたくない ◦ Amplify Flutter では
Storage(S3)だけ API KEY 認証がない ▪ 面倒臭い ◦ MinIO の非公式クライアント(minio)で回避 ▪ Amplify はどこへ・・・? 33
S3 も・・・ • 個人で使うアプリにわざわざ Cognito を入れたくない ◦ Amplify Flutter では
Storage(S3)だけ API KEY 認証がない ▪ 面倒臭い ◦ MinIO の非公式クライアント(minio)で回避 ▪ Amplify はどこへ・・・? 34 // 画像ファイルを S3 アップロード _uploadS3( Minio minio, Picture picture, String imagePath, String s3Bucket) async { final int pathIndexOf = picture.filePath.lastIndexOf('/'); final String fileName = (pathIndexOf == -1 ? picture.filePath : picture.filePath.substring(pathIndexOf + 1)); final String filePath = '$imagePath/$fileName'; try { await minio.fPutObject(s3Bucket, fileName, filePath); // ignore: avoid_print print('S3 upload $fileName succeeded'); return fileName; } catch (e) { // ignore: avoid_print print('S3 upload $fileName failed: $e'); return false; } }
トドメ • 距離計測と絡めてデータを取得したい ◦ DynamoDB ではできない ◦ DocumentDB は最近できるようになったようだけど高い ◦
PostGIS 使いたい 35
トドメ • 距離計測と絡めてデータを取得したい ◦ DynamoDB ではできない ◦ DocumentDB は最近できるようになったようだけど高い ◦
PostGIS 使いたい ◦ Supabase 使えばいいじゃん、PostgREST 使えるし https://supabase.com/ ▪ Amplify はどこへ・・・?(2 回目) 36
トドメ • 距離計測と絡めてデータを取得したい ◦ DynamoDB ではできない ◦ DocumentDB は最近できるようになったようだけど高い ◦
PostGIS 使いたい ◦ Supabase 使えばいいじゃん、PostgREST 使えるし https://supabase.com/ ▪ Amplify はどこへ・・・?(2 回目) 37 Future<List<SpotData>> searchNearSpot( SupabaseClient client, LatLng latLng, int distLimit) async { final PostgrestResponse selectResponse = await client.rpc('get_spots', params: { 'point_latitude': latLng.latitude, 'point_longitude': latLng.longitude, 'dist_limit': distLimit }).execute(); final List<dynamic> items = selectResponse.data; final List<SpotData> resultList = []; for (dynamic item in items) { final SpotData spotData = SpotData( item['distance'] as num, item['category_name'] as String, item['title'] as String, item['describe'] as String, LatLng((item['latitude'] as num).toDouble(), (item['longitude'] as num).toDouble()), PrefMuni(item['prefecture'] as String, item['municipality'] as String)); resultList.add(spotData); } return resultList; }
まとめ • Amplify : 頻出構成を最速で作るためのもの ◦ 自分専用の個人開発アプリとはユースケースが合わなくて当然 ◦ ユースケースが合わないものに対して無理に使うと、かえって 開発がつらくなる
◦ Flutter 以外の環境と比較するとまだ開発途上→うまく使えなく ても仕方がない 38
おまけ • 作っているアプリ(maptool) 39 Google Maps Platform ではなく Mapbox の地図を使用
←訪問(予定)先にピンを立てて、ピンに関連づけて写真撮影
おまけ • 作っているアプリ(maptool) 40 ←地図スタイル切り替え可
おまけ • 作っているアプリ(maptool) 41 ←地図スタイル切り替え可
おまけ 42 • 作っているアプリ(maptool)
おまけ 43 • 作っているアプリ(maptool) ←10km 以内にあるスポットを表示 (ほかにもいくつか機能あり)
おまけ 44 • 関連ブログ記事 ◦ https://qiita.com/hmatsu47/items/b98ef4c1a87cc0ec415d ◦ https://zenn.dev/hmatsu47/articles/846c3186f5b4fe ◦ https://zenn.dev/hmatsu47/articles/9102fb79a99a98
◦ https://zenn.dev/hmatsu47/articles/e81bf3c2bf00f8 ◦ https://qiita.com/hmatsu47/items/e4f7e310e88376d54009 ◦ https://qiita.com/hmatsu47/items/86a9c028bb5b3beeebdd ◦ https://qiita.com/hmatsu47/items/53ea68769c4fc2d76450