我只需要从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
}
任何有助于澄清我的想法以使其更简单,更好的想法都将受到赞赏。
我只想通过电子邮件检索一条记录,这一点我知道并且它是唯一的。
您正在寻找的是一种基于特定值(电子邮件)查询数据库的方法。通读Firebase数据库文档,您可以找到Filtering Data来解释您想要的内容。
为了满足您的情况,您需要做的是:
基于电子邮件对子元素进行排序,并使用EuqalTo()限制输出数据范围。
var db = FirebaseDatabase.Instance;
var mDatabase = db.GetReference("characters");
Query query = mDatabase.OrderByChild("Email")
.EqualTo("[email protected]");
创建子事件侦听器以检索过滤的数据。
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)
{}
}
寄存器MyChildEventListener
:
query.AddChildEventListener(new MyChildEventListener());