【问题标题】:Creating a firestore dynamic query at runtime - best approach?在运行时创建 Firestore 动态查询 - 最佳方法?
【发布时间】:2021-12-31 15:22:56
【问题描述】:

我正在做一个项目,我需要在文档上设置一个侦听器,以便在更改时轮询文档上特定地图字段的结果。这些是跟踪来自问题的数据聚合 - 附有示例结构。 根据下面的代码,这工作正常。

[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);
    });
}

但是,我不会提前知道要查询的字段究竟是什么,因为它是作为现场活动的一部分运行的。

是否可以在运行时动态创建 FirestoreData 类以匹配动态创建的查询路径?

或者...

对于我要解决的问题,是否有更好的方法?

非常感谢。

【问题讨论】:

  • 您是否考虑过使用不带类型的snapshot.GetValue("questions.q3") 而不是动态尝试生成Question1 类?这应该会给你一个包含值的字典,然后你可以按名称或动态访问它,如下所示:stackoverflow.com/questions/1276763/…
  • 我没有考虑过!那会简单 100 倍 :) 但是......我似乎无法在没有类型的情况下使用 GetValue? ` Dictionary data = snapshot.GetValue("questions.q3");` 抛出错误..
  • 来自firebase.google.com/docs/firestore/query-data/… 好像可以叫snapshot.ToDictionary
  • 所以,据我了解,我实际上无法使用文档参考定位该地图对象?例如:DocumentReference aggs = db.Collection("aggregations").Document("s1e1.questions.q3"); 在这种情况下,也许更好的方法是将整个文档解析为字典并解析它们?我希望能够以单个地图对象为目标,但也许这指向了对结构的重新思考......
  • 啊,我以为那是您的文档 ID。确实没有办法只加载文档的某些字段。如果您需要,通常是考虑使用子集合的时候。

标签: c# firebase google-cloud-firestore


【解决方案1】:

在这种情况下,最好的方法不是动态创建类,而是使用字典映射对象,映射值可以嵌套,并且您可以混合和匹配方法。例如,属性类可以包含字典,反之亦然。同样,您可以序列化为匿名类型,然后反序列化为属性类。 这是一个例子:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-25
    • 2012-01-07
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 2019-04-08
    • 2022-09-22
    相关资源
    最近更新 更多