如何在Xamarin-Android中从Firebase实时数据库中检索单个记录?

问题描述 投票:0回答:1

我只需要从Firebase Realtime数据库中读取一个实体,并将结果转换为与该结构匹配的C#类,但是我还没有找到明确的解决方案。有这棵树:

{
 "characters" : {
    "c1" : {
      "Email" : "[email protected]",
      "LastName" : "Pan",
      "Name" : "Peter"
    },
    "c2" : {
      "Email" : "[email protected]",
      "LastName" : "Potter",
      "Name" : "Harry"
    }
  }
}

以及这个C#类:

public class Character 
{
   public string Email {get; set; }
   public string Name { get; set; }
   public string LastName { get; set; }
}

我只想通过电子邮件检索一条记录,这一点我知道并且它是唯一的。但是,如果我确实包含NuGet程序包Xamarin.Firebase.Database,则其中不存在诸如OnceSingle<T>() or OnceSingleAsync<T>()之类的方法或扩展方法:

Character character = await FirebaseDatabase.Instance
  .GetReference(CharactersRoot)
  .OrderByChild("Email")
  .EqualTo("[email protected]") //Works until here
  .OnceSingleAsync<Character>(); //THIS METHOD IS NOT AVAILABLE. It doesn't work.

另一方面,通过包含软件包Xamarin.Forms.FirebaseWrapper,它是支持Firebase.Xamarin的前者OnceSingleAsync<T>()的升级,可以编写如下代码:

FirebaseClient fbClient= new FirebaseClient(Root);
var task = Task<Character>.Run(async () => 
            {
                return await fbClient.Child(CharactersRoot)
                    .OrderBy("Email")
                    .EqualTo("[email protected]")
                    .OnceSingleAsync<Character>().ConfigureAwait(false)
            });                 
            var character = task.Result;
            // do something with character...

但是它不起作用。它引发System.AggregateException:'发生一个或多个错误。 (响应状态代码不表示成功:400(错误请求)。)'

以下是我设法使它起作用的唯一方法,但是它性能不佳,因为它检索所有集合并在本地执行搜索。

    FirebaseClient fbClient= new FirebaseClient(Root);
    var task = Task<Character>.Run(async () =>
            {
                return await fbClient.Child(CharactersRoot)                                     
                                    .OnceAsync<Character>()
                                    .ConfigureAwait(false);
            });
            var character = task.Result
                            .Where(item => item.Object.Email == "[email protected]")
                            .Select(itm => itm.Object)
                            .FirstOrDefault();
            if (character != null)
            {
                //Do something with character
            }

任何有助于澄清我的想法以使其更简单,更好的想法都将受到赞赏。

c# performance xamarin firebase-realtime-database xamarin.forms
1个回答
0
投票

我只想通过电子邮件检索一条记录,这一点我知道并且它是唯一的。

您正在寻找的是一种基于特定值(电子邮件)查询数据库的方法。通读Firebase数据库文档,您可以找到Filtering Data来解释您想要的内容。

为了满足您的情况,您需要做的是:

  1. 基于电子邮件对子元素进行排序,并使用EuqalTo()限制输出数据范围。

    var db = FirebaseDatabase.Instance;
    var mDatabase = db.GetReference("characters");
    Query query = mDatabase.OrderByChild("Email")
                           .EqualTo("[email protected]");
    
  2. 创建子事件侦听器以检索过滤的数据。

    public class MyChildEventListener : Java.Lang.Object, IChildEventListener
    {
        public void OnCancelled(DatabaseError error)
        {}
    
        public void OnChildAdded(DataSnapshot snapshot, string previousChildName)
        {
            //this method will be triggered
            //snapshot's key is c2 namly harry potter
        }
    
        public void OnChildChanged(DataSnapshot snapshot, string previousChildName)
        {}
    
        public void OnChildMoved(DataSnapshot snapshot, string previousChildName)
        {}
    
        public void OnChildRemoved(DataSnapshot snapshot)
        {}
    }
    
  3. 寄存器MyChildEventListener

    query.AddChildEventListener(new MyChildEventListener());
    
© www.soinside.com 2019 - 2024. All rights reserved.