Skip to content

Firestore iOS: Exception when using SetData in Batch and Transaction with dictionary as input arguments #520

@weinamdev

Description

@weinamdev

Hi,

I encounter issue when using SetData method in Batch and Transaction with Dictionary<object,object> as input argument when using Firestore in iOS.

The SetData method working with string and number, however has exception if the value is other than string or number, like DateTimeOffset or any FieldValue data type provide by the Plugin.

The error/exception of the SetData method does not happen on android, only happen on iOS.

Using same set of input data Dictionary<object,object>, there is no issue using IDocumentReference.SetDataAsync on both iOS and Android

The error is related to data type conversion to NSDictionary / NSObject

Couldn't put object of type System.DateTimeOffset into NSDictionary
Couldn't put object of type Plugin.Firebase.Firestore.FieldValue into NSDictionary

Please refer sample code below for further investigation, thank you.

var db = CrossFirebaseFirestore.Current;
DateTimeOffset dateOnly = DateTimeOffset.Now;

// Test 3: SetDataAsync is working on both Android and iOS
 var doc3 = db.GetCollection("zzz").GetDocument("doc3");
 var data3 = new Dictionary<object, object>();
 data3.Add("DateField", dateOnly);
 data3.Add("FBFVField", FieldValue.ArrayUnion("Sub 1"));
 await doc3.SetDataAsync(data3, SetOptions.Merge());

 // Test 4: Batch is working on Android, but Error/Exception on iOS
 var doc4 = db.GetCollection("zzz").GetDocument("doc4");
 var data4 = new Dictionary<object, object>();
 data4.Add("FBFVField", FieldValue.ArrayUnion("Sub 1"));
 data4.Add("DateField", dateOnly);
 var batch = db.CreateBatch();
 _ = batch.SetData(doc4, data4, SetOptions.Merge());
 await batch.CommitAsync();

 // Test 5: Transaction is working on Android, but Error/Exception on iOS
 var doc5 = db.GetCollection("zzz").GetDocument("doc5");
 var data5 = new Dictionary<object, object>();
 data5.Add("FBFVField", FieldValue.ArrayUnion("Sub 1"));
 data5.Add("DateField", dateOnly);
 bool IsSuccess = true;
 await db.RunTransactionAsync<IFirestoreObject>(trans =>
 {
     try
     {
         _ = trans.SetData(doc5, data5, SetOptions.Merge());
     }
     catch (Exception ex)
     {
         ErrorLogger.Log(ex);
     }
     return null;

 }).ContinueWith(async t =>
 {
     if (t.IsCompleted)
     {
         IsSuccess &= t.Status == TaskStatus.RanToCompletion;
         if (!IsSuccess)
         {
             ErrorLogger.Log($"Transaction Failed! {t.Exception}");
         }
     }
 }); 

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions