プッシュ通知の送信履歴の表示について · Issue #1307 · NIFCLOUD-mbaas/UserCommunity、こちらの件で調査してはじめて知ったのですが、Flutter for Webで型判別をしていると微妙にハマります。
前提条件
ニフクラ mobile backendのデータストア(クラウドデータベース)では、文字列や数字、真偽値、配列、オブジェクトなど様々な形式を扱います。かつNoSQL型データベースなのでフィールド名も自由に付けられます。そのため、型指定する言語とは相性があまり良くなかったりします。
特にオブジェクトでデータが入っている中でも、ニフクラ mobile backendでは以下の型が特殊になります。
- 日時型
{__type: "Date", iso: "日付文字列"}
という形でデータが入っている - 位置情報型
{__type: "GeoPoint", latitude: 緯度の数値, longitude: 経度の数値}
という形でデータが入っている - リレーションデータ
{__type: "Pointer", className: "対象クラス名", objectId: "対象データのキー"}
という形でデータが入っている
このあたりを判別するために、入っているデータの型を調べる必要がありました。
やっていたこと
最初のコードです。
// データの型を調べる
if (value.runtimeType.toString() == '_JsonMap' ||
value.runtimeType.toString() ==
'_InternalLinkedHashMap<String, dynamic>') {
var map = value as Map;
if (map['className'] != null) {
// リレーションデータ
}
if (map.containsKey('__type') && map['__type'] == 'GeoPoint') {
// 位置情報型
}
if (map.containsKey('__type') && map['__type'] == 'Date') {
// 日時型
}
} else {
// それ以外
}
value.runtimeType.toString()
の値ですが、デバッグ環境では以下のようになります。 _InternalLinkedHashMap<String, dynamic>
になるのはスマホの場合だった覚えがあります。
userSettingValue is _JsonMap
deliveryExpirationTime is String
deliveryNumber is int
action is String
badgeIncrementFlag is bool
error is _JsonMap
target is List<dynamic>
ビルド環境での実行
いわゆる flutter build web
をやって生成されたコードでの実行結果です。 minified:F5
とか minified:bR
といった謎の文字列が入ってきます。この結果として、if文がうまく動かずに不具合が起きていました。
createDate is minified:bR
updateDate is minified:bR
acl is minified:n1
dialog is bool
error is minified:F5
objectId is String
deliveryTime is minified:F5
target is minified:r<dynamic>
修正後
あまり良くはないのですが、Mapとして評価してエラーになるかどうかで判別することにしました。
try {
var map = value as Map;
if (map['className'] != null) {
// リレーションデータ
}
if (map.containsKey('__type') && map['__type'] == 'GeoPoint') {
// 位置情報型
}
if (map.containsKey('__type') && map['__type'] == 'Date') {
// 日時型
}
_fields[name] = value;
} catch (e) {
_fields[name] = value;
}
is
で判別できそうな気もするのですが、過去にうまくいかなかった覚えがあるんですよね…(そのために runtimeType.toString()
を使っている覚えが)。ビルド環境によって変数の型が異なるのも面倒なので、今回のやり方の方がシンプルかなと思っています。
他に良い方法があれば、ぜひコメントで教えてください!
NCMBのDart/Flutterパッケージはncmb | Dart Packageにて公開しています。ぜひ試してみてください!