You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET MAUI中捕获Firebase的产品节点ID?

在.NET MAUI中使用firebase-database-dotnet获取Firebase节点Key的问题

我的Firebase数据结构如下:

products
  product1
    category: "dairy"
    description: "Sliced Arequipe cheese, ideal for accompanying your meals."
    name: "Arequipe Cheese Sliced"
    price: 10.99

  product10
    category: "dairy"
    description: "Box of 30 Kikes eggs."
    name: "Kikes Eggs 30 pcs"
    price: 3.99

我在.NET MAUI里使用firebase-database-dotnet包操作Firebase,需要获取产品对应的节点Key(比如product1、product10)。但现有获取产品的方法仅返回产品对象,无法捕获节点Key:

public async Task<IEnumerable<T>> GetItemsAsync(bool forceRefresh = false)
{
    try
    {
        var firebaseObjects = await _query
            .OnceAsync<T>();

        return firebaseObjects
            .Select(x => x.Object); // 仅返回FirebaseObject<T>中的Object部分
    }
    catch (Exception ex)
    {
        return null;
    }
}

现在要实现保存选中产品的方法,需要拿到对应产品的节点ID,示例代码如下:

[RelayCommand]
public async Task SaveProduct(Product product)
{
    // 这里需要用GetItemsAsync获取现有产品,但如何捕获选中产品的节点ID(如'product1'或'product10')?
}

想请教:

  1. 能否将节点ID包含在产品的数据表中?
  2. 这么做是否属于不良实践?
  3. 如何修改现有方法,同时获取节点Key和产品数据?

解决方案

1. 能否将节点ID存入数据表?是否为不良实践?

可以将节点ID存入数据表,但这属于不推荐的不良实践:

  • Firebase节点Key本身就是唯一标识,重复存储会冗余占用存储空间;
  • 若节点Key需要变更(虽场景极少),需同时更新节点Key与数据表中的ID,极易出现数据不一致;
  • 从Firebase查询时,通过节点Key即可直接定位数据,无需在数据内重复存储。

2. 修改现有方法,同时获取节点Key与产品数据

有两种常用实现方式:

方式一:给Product类新增Id属性

首先在Product类中添加Id属性,用于存储节点Key:

public class Product
{
    public string Id { get; set; }
    public string Category { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
}

然后修改GetItemsAsync方法,将Firebase返回的FirebaseObject<T>的Key赋值给产品对象的Id属性:

public async Task<IEnumerable<T>> GetItemsAsync(bool forceRefresh = false)
{
    try
    {
        var firebaseObjects = await _query.OnceAsync<T>();
        return firebaseObjects.Select(x => 
        {
            // 针对Product类型直接强转赋值
            if (x.Object is Product product)
            {
                product.Id = x.Key;
            }
            // 通用场景可使用反射适配任意T类型
            // var idProperty = typeof(T).GetProperty("Id");
            // if (idProperty != null) idProperty.SetValue(x.Object, x.Key);
            
            return x.Object;
        });
    }
    catch (Exception ex)
    {
        return null;
    }
}

调用该方法后,每个Product对象的Id属性就对应Firebase的节点Key,在SaveProduct中直接使用product.Id即可获取节点ID。

方式二:返回包含Key和数据的自定义包装类

若不想修改Product类,可创建自定义类包装节点Key与产品数据:

public class FirebaseItem<T>
{
    public string Key { get; set; }
    public T Data { get; set; }
}

修改GetItemsAsync方法返回该自定义类型:

public async Task<IEnumerable<FirebaseItem<T>>> GetItemsAsync(bool forceRefresh = false)
{
    try
    {
        var firebaseObjects = await _query.OnceAsync<T>();
        return firebaseObjects.Select(x => new FirebaseItem<T>
        {
            Key = x.Key,
            Data = x.Object
        });
    }
    catch (Exception ex)
    {
        return null;
    }
}

在SaveProduct方法中,通过产品的唯一属性(如名称、价格)匹配对应的节点Key:

[RelayCommand]
public async Task SaveProduct(Product product)
{
    var allItems = await GetItemsAsync();
    // 通过产品的唯一标识匹配对应节点Key
    var matchedItem = allItems.FirstOrDefault(item => 
        item.Data.Name == product.Name && item.Data.Price == product.Price);
    
    if (matchedItem != null)
    {
        string productKey = matchedItem.Key;
        // 使用productKey执行后续保存逻辑
    }
}

内容的提问来源于stack exchange,提问作者Luis Julio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:22:41