リファレンスやgithubを見ているときに気になる英単語

garbled characters

https://github.com/flutter/flutter/issues/55283

consecutive

https://dart.dev/articles/libraries/creating-streams

Splits a stream of consecutive strings into lines.

decipher

https://developer.android.com/codelabs/basic-android-kotlin-training-update-data-room#4

It is simple and easy to understand; you are left to decipher it on your own.

two decimal places

https://developer.android.com/codelabs/basic-android-kotlin-training-update-data-room#4

round the price to two decimal places using the format() function and assign it to a val named price

populate

Flutter How to Populate ListView on app launch with sqflite? - Stack Overflow

Flutter How to Populate ListView on app launch with sqflite?

hoist

https://developer.android.com/codelabs/jetpack-compose-state#5

This text field doesn't hoist its state when it should.

volatile

https://developer.android.com/codelabs/basic-android-kotlin-training-persisting-data-room#6

The value of a volatile variable will never be cached, and all writes and reads will be done to and from the main memory.

underlying

Persist data with Room  |  Android Developers

The functionality of the DAO is to hide all the complexities involved in performing the database operations in the underlying persistence layer from the rest of the application.

inflate the layout

https://developer.android.com/codelabs/basic-android-kotlin-training-intro-room-flow#7

Override and implement onCreateViewHolder() and inflate the layout and set the onClickListener() to call onItemClicked() for the item at the current position.

That's it for

https://developer.android.com/codelabs/basic-android-kotlin-training-intro-room-flow#6

That's it for setting up your app's model.

acronym

Introduction to Room and Flow  |  Android Developers

While DAO is an acronym, naming conventions for Kotlin code only capitalize the first letter in acronyms, thus the name ScheduleDao and not ScheduleDAO.

come in handy

Introduction to Room and Flow  |  Android Developers

Your knowledge of SQL from the previous codelab will come in handy when defining the DAO.

stick

https://developer.android.com/codelabs/basic-android-kotlin-training-intro-room-flow#3

you'll stick with Kotlin date formatting functions.

Side by side

https://developer.android.com/studio/projects/install-ndk

Select the NDK (Side by side) and CMake checkboxes.

補足

https://en.wikipedia.org/wiki/Side-by-side_assembly

gracefully

https://developer.android.com/guide/webapps/managing-webview

The app can recover gracefully by creating a new WebView instance in the foreground.

anticipate

Get data from the internet  |  Android Developers

Inside the try block you perform the code where you anticipate an exception

take advantage of

https://developer.android.com/distribute

Take advantage of Google Play features to grow your startup

represent

https://developer.android.com/codelabs/kotlin-android-training-create-and-add-fragment?hl=ja#0

In this codelab, you learn about fragments, which represent a behavior or a portion of the user interface in an activity.

node-apple-receipt-verify PurchasedProductsにoriginalTransactionIdがない

Adding in-app purchases to your Flutter app  |  Google Codelabs

import * as appleReceiptVerify from "node-apple-receipt-verify";

// Add typings for missing property in library interface.
declare module "node-apple-receipt-verify" {
  interface PurchasedProducts {
    originalTransactionId: string;
  }
}

回避策は上に書いてある通りです。Interfacesがマージできるという性質を利用してます。

また、PurchasedProductsにoriginalTransactionIdが無いというのは下記に無いということになります。

DefinitelyTyped/index.d.ts at 173aa9174685d78871a5c035b74d856f4aef9cc8 · DefinitelyTyped/DefinitelyTyped · GitHub

tsconfigでよく問題になるオプション

随時追記

esModuleInterop

https://www.typescriptlang.org/tsconfig#esModuleInterop

  • Recommended: true
  • Default: false

falseの場合これで動く

import * as parse from 'csv-parse/lib/sync';

parse(input, {
      columns: true, // 一行目をフィールドのkeyとして使用する
      skip_empty_lines: true,
      cast: (value, context) => value === '' ? null : value
    });

trueならこっちに書き換えないといけない

import parse from 'csv-parse/lib/sync';

flutter firestore_ref 3階層のコレクションをFactory constructorsで取得しやすくしてみる

/**
 * 親の親がorganizations,親がprojects
 */
class TeamsRef extends CollectionRef<Team, TeamDoc, TeamRef> {
  TeamsRef(this.cr) : super(cr);
  final CollectionReference<Map<String, dynamic>> cr;

  // 作ってみたもののあんまり意味がない
  factory TeamsRef.parentDoc(ProjectDoc doc) =>
      TeamsRef(doc.projectRef.ref.collection('teams'));

  // 呼び出し元が冗長
  factory TeamsRef.parentRef(ProjectRef parentRef) =>
      TeamsRef(parentRef.ref.collection('teams'));

  // 呼び出しもとは簡潔
  factory TeamsRef.ids(String grandParentId, String parentId) =>
      TeamsRef(FirebaseFirestore.instance
          .collection('organizations/$grandParentId/projects/$parentId/teams'));

  /* collectionGroupだと型が合わない
  factory TeamsRef.parentId(String parentId) =>
      TeamsRef(FirebaseFirestore.instance.collectionGroup(collectionPath));
  */

  @override
  JsonMap encode(Team data) => replacingTimestamp(json: data.toJson());

  @override
  TeamDoc decode(DocumentSnapshot<JsonMap> snapshot, TeamRef docRef) {
    return TeamDoc(
      docRef,
      Team.fromJson(snapshot.data()!),
    );
  }

  @override
  TeamRef docRef(DocumentReference<JsonMap> ref) => TeamRef(
        ref: ref,
        teamsRef: this,
      );
}

factoryコンストラクタをこんな風に使っていいかはわかってないですが、 一応期待通り動きます。

flutter_firestore_practice/team.dart at main · na8esin/flutter_firestore_practice · GitHub

Firestore data bundles から余分な数字を取り除いて整形されたjsonでファイルに出力する

FlutterFireが新しくなったという下記の記事を見てdata bundlesのサンプルを書いてみることにしました。

invertase.io

data bundles自体の詳細はこっち

Cloud Firestore data bundles  |  Firebase

サンプルを書いてるうちに中身を出力してみたくなりました。

中身はほぼjsonですが余分な数字が入ってるのと、複数のjsonオブジェクトがちゃんと連結されてないので配列可しました。

data bundleから余分な物を取り除いて整形してファイルに出力 · na8esin/firebase-practice@2cc22e7 · GitHub

Android エミュレータでGoogle アカウントに自動でログインする方法はないのか?

Play Billingなどを使う場合は、前もってgoogleアカウントにログインしておく必要があります。

エミュレータを初期化するなどすると消えてしまうのでその度ログインするのは面倒です。

今のところUI Automatorだけ成功

flutter_driverでなんとかする

現状では無理のようです。

flutter_driver can't interact with native elements · Issue #34345 · flutter/flutter · GitHub

flutter driver and android permissions · Issue #12561 · flutter/flutter · GitHub

ただ、個人的にはfind.text()とか使っていけそうな気がする。。。

Robo test

Test Labにアップロードしてテストする。flutter driveを使ったIntegration testが実行可能

Robo スクリプトはどう?

Robo テストを使ってみる  |  Firebase

注: Robo スクリプトの記録時に、テスト対象アプリの外部で行われた操作はキャプチャされません。たとえば、FacebookTwitter などのソーシャル アプリからのログインは記録されません。

無理そう。

UI Automator

複数のアプリの UI をテストできるらしい

成功したのでソースを公開

android_uiautomator_sample/GooglePlayTest.kt at main · na8esin/android_uiautomator_sample · GitHub

flutterで作ったbuttonもクリックできる

purchase画面の¥100ボタンのクリックに成功 · na8esin/flutter_in_app_purchase@d770a50 · GitHub

ただ、なぜかテキストがcontent-descに入る

f:id:ta_watanabe:20210714172611p:plain
uiautomatorviewerのdump結果

flutterとUI Automatorの連携は?

この辺りで議論中
Provide better support for UiAutomator · Issue #32062 · flutter/flutter · GitHub

Support UIAutomator tests of Flutter module in existing android app · Issue #53383 · flutter/flutter · GitHub

Android Test Orchestrator

uiautomatorviewerがjdk8しか対応してない

android - uiautomatorviewer - Error: Could not create the Java Virtual Machine - Stack Overflow

その上m1 macでは別の問題がある

Broken GUI of UIAutomatorViewer on MacOS Big Sur · Issue #911 · android/android-test · GitHub

swt.jarのダウンロードがわかりづらい

f:id:ta_watanabe:20210714155344p:plain f:id:ta_watanabe:20210714155340p:plain

当たり前かもしれませんが、armの方だとだめです。 間違って、ダウンロードして、uiautomatorviewerを実行したら、~/.swtを削除しないといけません。

espresso

email,passwordを入力するときは別のアプリになるから無理かもしれない。

flutter espresso

同上?

ソース内でベタっと書いてGoogle OAuthする

OpenID Connect  |  Google Identity  |  Google Developers

googleのUIを経由しないで、emailとpasswordを送信できるインターフェースが見つからない。 当たり前と言えば当たり前。

adb

インテントは起動できるみたいだけど、そこから先が不明。 ちなみに、RC_SIGN_IN