Iain Simons
Iain Simons

Reputation: 21

Creating a firestore dynamic query at runtime - best approach?

I’m working on a project where I need to set-up a listener on a document, so I can poll the results of specific map fields on it as they change. These are tracking data aggregations from questions - example structure attached. This is working fine, as per the code below.

[FirestoreData]
public class Question1
{
   
    [FirestoreProperty("I do")]
    public string beer { get; set; }

    [FirestoreProperty("I don't")]
    public string wine { get; set; }
}

public void getDataFeed()
{
 
    FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
    DocumentReference aggs = db.Collection("aggregations").Document("s1e1");

   ListenerRegistration aggregation =  aggs.Listen(snapshot =>
    {
       Question1 question1 = snapshot.GetValue<Question1>("questions.q3");
       Debug.Log(question1.beer);
       Debug.Log(question1.wine);
    });
}

However, I won’t know in advance exactly what the fields to be queried will be, as it’s running as part of a live event.

Is it possible to dynamically create a FirestoreData class at runtime to match a dynamically created query path?

Or...enter image description here

Is there simply a better approach for the problem I'm trying to solve?

Many thanks in advance.

Upvotes: 1

Views: 236

Answers (1)

Pablo
Pablo

Reputation: 68

In this case, instead of dynamically creating classes the best approach would be mapping the objects with dictionaries, that map values can be nested, and you can mix and match approaches. For example, an attributed class can contain a dictionary or vice versa. Similarly, you can serialize as an anonymous type then deserialize as an attributed class. This is an example from:

https://cloud.google.com/dotnet/docs/reference/Google.Cloud.Firestore/latest/datamodel#mapping-with-attributed-classes

    FirestoreDb db = FirestoreDb.Create(projectId);
    // Create a document with a random ID in the "cities" collection.
    CollectionReference collection = db.Collection("cities");
    Dictionary<string, object> city = new Dictionary<string, object>
    {
        { "Name", "Los Angeles" },
        { "Country", "USA" },
        { "State", "CA" },
        { "Capital", false },
        { "Population", 3900000L }
    };
    DocumentReference document = await collection.AddAsync(city);
    
    // Fetch the data back from the server and deserialize it.
    DocumentSnapshot snapshot = await document.GetSnapshotAsync();
    Dictionary<string, object> cityData = snapshot.ToDictionary();
    Console.WriteLine(cityData["Name"]); // Los Angeles

Upvotes: 1

Related Questions