EddyVerbruggen / nativescript-plugin-firebase

:fire: NativeScript plugin for Firebase
https://firebase.google.com
MIT License
1.01k stars 446 forks source link

Array could not contain DocumentReference #1632

Open robario opened 4 years ago

robario commented 4 years ago

It seems to me that arrayUnion is failing to convert.

Code

const dataRef = firestore.docRef("data/QmqiRWBxEAUtYS8VBaTS4BsMKfF3");
firestore.docRef("docs/1").update({
  validRef: dataRef,
  invalidRef: firestore.FieldValue.arrayUnion(dataRef),
});

Result

docs/VbwvR8pPaTdk8CUGtevgjkuZalf2: {
  validRef: DocumentReference {
    _firestore: Firestore {},
    _path: ResourcePath { segments: [Array] },
    _converter: {}
  },
  invalidRef: [
    {
      firestore: {},
      android: {},
      path: 'data/QmqiRWBxEAUtYS8VBaTS4BsMKfF3',
      id: 'QmqiRWBxEAUtYS8VBaTS4BsMKfF3',
      parent: [Object],
      discriminator: 'docRef'
    },
}

Workaround

Android

I don't know which is better (or neither).

 firebase.toHashMap = obj => {
+  if (isDocumentReference(obj)) {
+    return obj.android;
+  }
   const node = new java.util.HashMap();

or

           if (fieldValue.type === "ARRAY_UNION") {
             // nested arrays are not allowed, so harden against wrong usage: arrayUnion(["foo", "bar"]) vs arrayUnion("foo", "bar")
             let values: Array<any> = Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value;
-            values = values.map(v => typeof (v) === "object" ? firebase.toHashMap(v) : v);
+            values = values.map(v => typeof (v) === "object" ? (isDocumentReference(v) ? v.android : firebase.toHashMap(v)) : v);
             node.put(property, com.google.firebase.firestore.FieldValue.arrayUnion(values));
           } else if (fieldValue.type === "ARRAY_REMOVE") {
             let values: Array<any> = Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value;
-            values = values.map(v => typeof (v) === "object" ? firebase.toHashMap(v) : v);
+            values = values.map(v => typeof (v) === "object" ? (isDocumentReference(v) ? v.android : firebase.toHashMap(v)) : v);
             node.put(property, com.google.firebase.firestore.FieldValue.arrayRemove(values));
           } else if (fieldValue.type === "INCREMENT") {

iOS

     if (fieldValue.type === "ARRAY_UNION") {
       // nested arrays are not allowed, so harden against wrong usage: arrayUnion(["foo", "bar"]) vs arrayUnion("foo", "bar")
-      return FIRFieldValue.fieldValueForArrayUnion(Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value);
+      let values = Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value;
+      values = values.map(function (v) { return typeof (v) === "object" ? fixSpecialFields(v) : fixSpecialField(v); });
+      return FIRFieldValue.fieldValueForArrayUnion(values);
     } else if (fieldValue.type === "ARRAY_REMOVE") {
-      return FIRFieldValue.fieldValueForArrayRemove(Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value);
+      let values = Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value;
+      values = values.map(function (v) { return typeof (v) === "object" ? fixSpecialFields(v) : fixSpecialField(v); });
+      return FIRFieldValue.fieldValueForArrayUnion(values);
    } else if (fieldValue.type === "INCREMENT") {