googlearchive / firebase-dart

Dart wrapper for Firebase
https://pub.dev/packages/firebase
404 stars 144 forks source link

[ Dartify ] Datasnapshot.val() failing #364

Closed tperraut closed 3 years ago

tperraut commented 3 years ago

I tried to use firebase database from firebase.dart package. Everything is working fine with primitive types but it seems the val() and toJson() functions on DataSnapshot are failing with exception :

Expected a value of type 'JSObject<Qp>', but got one of type 'NativeJavaScriptObject'

Calling numChildren() or all other function not depending on dartify helper return the expected values.

final complexObjectCollection = await database().ref("/rest/scooters").once("value");
final primitiveType = event.snapshot.child("S000893/online");
print(primitiveType.val()) // print true
print(complexObjectCollection.val()) // print nothing
print("Never shown") // this never print

The collection "/rest/scooters" have objects like the following inside :

{
  "adopted" : true,
  "batteryAlertSentTo" : "",
  "batteryLevel" : 0,
  "charging" : false,
  "checkedoutForOPS" : false,
  "currentSpeedMode" : "2",
  "defaultSpeedMode" : 2,
  "gender" : "female",
  "ghost" : false,
  "iotCode" : "XX",
  "iotType" : "XX",
  "lastTelemetryUpdate" : "2020-07-17T12:15:33Z",
  "locked" : true,
  "macAddress" : "XX",
  "name" : "Enable ⚡",
  "needsCollection" : false,
  "online" : true,
  "position" : {
    "latitude" : 44.83238,
    "longitude" : -0.53731
  },
  "reason" : "0",
  "region" : "Bordeaux",
  "status" : "HIDDEN",
  "vehicleCode" : "XX"
}

So something is happening in the dartify helper, it seems to be related to firestore types like GeoPoint and dart being unable to cast an object with latitude and longitude fields to it as it is actually not a firestore GeoPoint object.

Thank you for your work

kevmoo commented 3 years ago

I just tried to reproduce this in tests and had to problem

diff --git a/firebase/test/database_test.dart b/firebase/test/database_test.dart
index b7b382d..3db4051 100644
--- a/firebase/test/database_test.dart
+++ b/firebase/test/database_test.dart
@@ -60,6 +60,43 @@ void main() {
       key = null;
     });

+    test('complex', () async {
+      final myRef = database.ref('/rest/scooters');
+
+      final myKey = await myRef.push({
+        'adopted': true,
+        'batteryAlertSentTo': '',
+        'batteryLevel': 0,
+        'charging': false,
+        'checkedoutForOPS': false,
+        'currentSpeedMode': '2',
+        'defaultSpeedMode': 2,
+        'gender': 'female',
+        'ghost': false,
+        'iotCode': 'XX',
+        'iotType': 'XX',
+        'lastTelemetryUpdate': '2020-07-17T12:15:33Z',
+        'locked': true,
+        'macAddress': 'XX',
+        'name': 'Enable ⚡',
+        'needsCollection': false,
+        'online': true,
+        'position': {'latitude': 44.83238, 'longitude': -0.53731},
+        'reason': '0',
+        'region': 'Bordeaux',
+        'status': 'HIDDEN',
+        'vehicleCode': 'XX'
+      }).future;
+
+      print(myKey.key);
+
+      final complexObjectCollection =
+          await database.ref('/rest/scooters').once('value');
+      final snapshot = complexObjectCollection.snapshot;
+      print(snapshot.val());
+      print(snapshot.toJson());
+    });
+
     test('has toJson', () {
       var toJsonString = ref.toJson() as String;
       expect(toJsonString, startsWith(databaseUrl));

Let me know if you can come up with a failing test. I'd love to help fix this!

tperraut commented 3 years ago

If I remove the lines :

  if (util.hasProperty(jsObject, 'latitude') &&
      util.hasProperty(jsObject, 'longitude') &&
      js.objectKeys(jsObject).length == 2) {
    // This is likely a GeoPoint – return it as-is
    return jsObject as GeoPoint;
  }

In the dartify helper, everything is working fine. I will come with a working test soon.

kevmoo commented 3 years ago

Ooo! Maybe https://github.com/FirebaseExtended/firebase-dart/pull/379 fixes this, too!

kevmoo commented 3 years ago

@tperraut – please grab the latest here and verify things are fixed!

You need help doing that, let me know!