diff --git a/lib/src/app.dart b/lib/src/app.dart index 8d168d1..3e0d597 100644 --- a/lib/src/app.dart +++ b/lib/src/app.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:firebase_admin/src/firestore/firestore.dart'; import 'package:firebase_admin/src/storage.dart'; import '../firebase_admin.dart'; diff --git a/lib/src/firestore/firestore.dart b/lib/src/firestore/firestore.dart index 39cab1b..b616fde 100644 --- a/lib/src/firestore/firestore.dart +++ b/lib/src/firestore/firestore.dart @@ -32,18 +32,18 @@ class Firestore implements FirebaseService { CollectionReference> collection(String id) { return CollectionReference( firestore: this, - path: id, fromFirestore: fromFirestore, toFirestore: toFirestore, + path: id, ); } DocumentReference> doc(String id) { return DocumentReference( firestore: this, - path: id, fromFirestore: fromFirestore, toFirestore: toFirestore, + path: id, ); } @@ -53,8 +53,8 @@ class Firestore implements FirebaseService { }) { return Transaction.run( firestore: this, - handler: handler, timeout: timeout, + handler: handler, ); } } diff --git a/lib/src/firestore/query.dart b/lib/src/firestore/query.dart index 2f24547..ce6d62a 100644 --- a/lib/src/firestore/query.dart +++ b/lib/src/firestore/query.dart @@ -13,8 +13,7 @@ class Query { final FromFirestore fromFirestore; final String path; - // FIXME: Remove nullability - final StructuredQuery? _query; + final StructuredQuery _query; Query({ required this.firestore, @@ -94,7 +93,7 @@ class Query { return Filter( fieldFilter: FieldFilter( field: FieldReference(fieldPath: field), - op: 'LESS_THAN', + op: op, value: serializeValue(value), ), ); @@ -153,7 +152,7 @@ class Query { Cursor? startAt, List? where, }) { - final prevWhere = _query?.where; + final prevWhere = _query.where; final filters = [ if (prevWhere != null) if (prevWhere.compositeFilter?.filters != null) @@ -168,13 +167,13 @@ class Query { fromFirestore: fromFirestore, path: path, query: StructuredQuery( - endAt: endAt ?? _query?.endAt, - from: _query?.from, // ??? - limit: limit ?? _query?.limit, + endAt: endAt ?? _query.endAt, + from: _query.from, // ??? + limit: limit ?? _query.limit, offset: null, // ??? - orderBy: orderBy != null ? [...?_query?.orderBy, orderBy] : _query?.orderBy, + orderBy: orderBy != null ? [...?_query.orderBy, orderBy] : _query.orderBy, select: null, // Returns all document fields. - startAt: startAt ?? _query?.startAt, + startAt: startAt ?? _query.startAt, where: filters.isEmpty ? null : (filters.singleOrNull ?? @@ -190,11 +189,12 @@ class Query { } class QuerySnapshot { - final List _docs; final Firestore firestore; final ToFirestore toFirestore; final FromFirestore fromFirestore; + final List _docs; + @internal const QuerySnapshot({ required this.firestore, diff --git a/lib/src/firestore/transaction.dart b/lib/src/firestore/transaction.dart index cdf32a9..52a5812 100644 --- a/lib/src/firestore/transaction.dart +++ b/lib/src/firestore/transaction.dart @@ -64,9 +64,9 @@ class Transaction { @internal static Future run({ required Firestore firestore, - required Future Function(Transaction transaction) handler, Duration timeout = const Duration(seconds: 30), // int maxAttempts = 5, TODO: Implement it + required Future Function(Transaction transaction) handler, }) async { assert(timeout.inMilliseconds > 0, 'Transaction timeout must be more than 0 milliseconds'); diff --git a/lib/src/firestore/utils/document_snapshot.dart b/lib/src/firestore/utils/document_snapshot.dart index 8fcacfa..bfae562 100644 --- a/lib/src/firestore/utils/document_snapshot.dart +++ b/lib/src/firestore/utils/document_snapshot.dart @@ -44,5 +44,5 @@ class _RawDocumentSnapshot extends DocumentSnapshot> { ); @override - Map data() => deserializeData(_document.fields!); + Map data() => deserializeData(firestore, _document.fields!); } diff --git a/lib/src/firestore/utils/serialization.dart b/lib/src/firestore/utils/serialization.dart index 5d151ce..fa4f225 100644 --- a/lib/src/firestore/utils/serialization.dart +++ b/lib/src/firestore/utils/serialization.dart @@ -1,38 +1,46 @@ import 'package:firebase_admin/src/firestore/document.dart'; import 'package:googleapis/firestore/v1.dart'; +import 'package:maps_toolkit/maps_toolkit.dart' as maps_toolkit; + +import '../firestore.dart'; Map fromFirestore(DocumentSnapshot> snapshot) => snapshot.data(); Map toFirestore(Map value) => value; -Map deserializeData(Map fields) { - return fields.map((key, value) => MapEntry(key, deserializeValue(value))); +Map deserializeData(Firestore firestore, Map fields) { + return fields.map((key, value) => MapEntry(key, deserializeValue(firestore, value))); } Map serializeData(Map data) { return data.map((key, value) => MapEntry(key, serializeValue(value))); } -dynamic deserializeValue(Value value) { +dynamic deserializeValue(Firestore firestore, Value value) { if (value.arrayValue != null) { - return value.arrayValue!.values!.map(deserializeValue).toList(); + return value.arrayValue!.values!.map((value) => deserializeValue(firestore, value)).toList(); } else if (value.booleanValue != null) { return value.booleanValue!; } else if (value.bytesValue != null) { - return null; + return null; // TODO: Add support to it } else if (value.doubleValue != null) { return value.doubleValue!; } else if (value.geoPointValue != null) { - return null; + return maps_toolkit.LatLng(value.geoPointValue!.latitude!, value.geoPointValue!.longitude!); } else if (value.integerValue != null) { return int.parse(value.integerValue!); } else if (value.mapValue != null) { - return deserializeData(value.mapValue!.fields!); + return deserializeData(firestore, value.mapValue!.fields!); } else if (value.nullValue != null) { return null; } else if (value.referenceValue != null) { - return null; + return DocumentReference>( + firestore: firestore, + fromFirestore: fromFirestore, + toFirestore: toFirestore, + path: value.referenceValue!, + ); } else if (value.stringValue != null) { return value.stringValue!; } else if (value.timestampValue != null) { @@ -46,11 +54,13 @@ Value serializeValue(dynamic data) { booleanValue: data is bool ? data : null, bytesValue: null, doubleValue: data is double ? data : null, - geoPointValue: null, + geoPointValue: data is maps_toolkit.LatLng + ? LatLng(latitude: data.latitude, longitude: data.longitude) + : null, integerValue: data is int ? '$data' : null, mapValue: data is Map ? MapValue(fields: serializeData(data)) : null, nullValue: data == null ? 'nullValue' : null, - referenceValue: null, + referenceValue: data is DocumentReference> ? data.path : null, stringValue: data is String ? data : null, timestampValue: data is DateTime ? '${data.microsecondsSinceEpoch}' : null, ); diff --git a/pubspec.yaml b/pubspec.yaml index d7d47a0..2bdaaf3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: http: ^0.13.0 crypto_keys: ^0.3.0 collection: ^1.15.0 + maps_toolkit: ^2.0.1 gcloud: ^0.8.0 firebaseapis: ^0.1.2 snapshot: ^0.2.5