BETA

[Flutter] 夏休み中に学んだこと(Firebase, GoogleDrive API)

投稿日:2020-08-09
最終更新:2020-08-10

参考記事

Firebaseについて

Firebase機能使用時に、アプリがクラッシュする

アプリ起動時にクラッシュする

参考記事: dart - Firebase phone auth flutter crash - Stack Overflow」」

google_sign_inパッケージの説明に書いてあるが、iOSの場合はInfo.plistに以下のような記載が必要だった。

<!-- Put me in the [my_project]/ios/Runner/Info.plist file -->  
<!-- Google Sign-in Section -->  
<key>CFBundleURLTypes</key>  
<array>  
    <dict>  
        <key>CFBundleTypeRole</key>  
        <string>Editor</string>  
        <key>CFBundleURLSchemes</key>  
        <array>  
            <!-- TODO Replace this value: -->  
            <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->  
            <string>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string>  
        </array>  
    </dict>  
</array>  
<!-- End of the Google Sign-in Section -->  

Cloud Storageにアクセスする際にクラッシュする

参考記事: iOS で使ってみる | Firebase

公式ドキュメントをよく読もう。Podfileに追記が必要だった。

pod 'Firebase/Storage'  

Storageにアクセスした際にエラーが起きる

参考記事: Firebase.Storage.StorageExceptionクラスリファレンス

今回でたのは、ErrorNotAuthorized = -13021で、認証はできているけど権限がないよというエラー。
原因は、Storageのアクセスルールに「自分で作ったファイルしか読み書きできないよ」というルールを作った上で、Storgageのルートパスにファイルを作ろうとしていたことだった。

セキュリティルール: 基本的なセキュリティルール | Firebase

Google Drive apiについて

  • サインインしているアカウントの所有するGoogle Driveにアプリ専用のフォルダを作ってデータを保存することができる。
  • アプリ専用のフォルダは、ブラウザなどでGoogle Driveにアクセスすれば容量などは見られるが、中に何があるかは見られない。
  • ダウンロードAPIがすごく遅い。数MBで4~5分かかる。アップロードは速い。
  • アプリのバックアップで使おうとしていたが、復元の際に同期的にダウンロードを待機するような使い方では遅すぎて使いものにならない。逆にメモアプリなど、大量にデータを入れても数KBにしかならないようなら使えそう。
  • 代替案としては、FirebaseのサービスであるCloud Storageを使う。(ダウンロード速度は未確認)
  • ただし、Cloud Storageはアプリ単位で、保存容量やデータ転送量、リクエスト回数?などに応じて料金がかかるので、アプリの利用者が多い場合は無料利用枠に収まらなくなるため注意が必要。
  • ファイルではなく、DBに保存してあるデータなどを保存したい場合はCloud Firestoreが良いかもしれない。

その他

なんでもかんでもasync/awaitを使えば良いというものではない

ダウンロードなどの1つ1つの処理が重い処理を連続して行う時、awaitで待たせてしまうと処理全体が終了するのが遅くなってしまう場合がある。そういった場合はFuture.wait(futures);を使って並行に処理させると多少ましになる。

// 時間がかかるVer  
Future<void> downloadAllFiles(List<String> fileRefs) async {  
  for (int i = 0; i < fileRefs.length; i++) {  
    final String fileId = fileRefs[i].id;  
    final File file = await download(fileId);  
    await saveLocal(file);  
  }  
}  

// 多少ましVer  
Future<void> downloadAllFiles(List<String> fileRefs) async {  
  final List<Future<File>> futures =  
        List.generate(fileRefs.length, (int index) {  
      return download(fileRefs[i].id);  
    },  
  );  
  final List<File> downloadFiles = await Future.wait(futures);  
  // save ~~~   
}  

実験

void main() {  
  awaitEach();  
  awaitAll();  
}  

Future<void> awaitEach() async {  
  DateTime start = DateTime.now();  

  for (int i = 0; i < 5; i++) {  
    await Future.delayed(Duration(seconds: 1));  
  }  

  DateTime end = DateTime.now();  
  print('awaitEach: ${end.difference(start)}');  
}  

Future<void> awaitAll() async {  
  DateTime start = DateTime.now();  

  final futures = List.generate(5, (_) => Future.delayed(Duration(seconds: 1)));  
  await Future.wait(futures);  

  DateTime end = DateTime.now();  
  print('awaitAll: ${end.difference(start)}');  
}  

結果

awaitAll: 0:00:01.004000  
awaitEach: 0:00:05.024000  
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@popy1017の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう