Firebase数据快照返回空值。

huangapple go评论105阅读模式
英文:

Firebase Datasnapshot returns null value

问题

我想从这个节点中检索这个值("id"),但我得到的值是null。我已经搜索了很多解决方案,可能与异步方式或其他什么有关,我猜?

这是数据库,突出显示的节点是我想要获取的值:

Firebase数据快照返回空值。

这是我的代码:

reference = FirebaseDatabase.getInstance().getReference();
id = null;
Query lastQuery = reference.child("Donation Request").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener()
{
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot)
    {
        if (dataSnapshot.child("id").exists())
        {
            id = dataSnapshot.child("id").getValue().toString();
            int index = Integer.parseInt(id) + 1;
            id = Integer.toString(index);
            Toast.makeText(getApplicationContext(), "It works!!!", Toast.LENGTH_SHORT).show();
        }
        else
        {
            id = "1";
            Toast.makeText(getApplicationContext(), "It doesn't work.", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError)
    {

    }
});

如果有人能帮助我解决这个问题,将不胜感激!

英文:

I want to retrieve this value from this node ("id"), and the value i get is null. I have googled so many solutions that this might have to do with asynchronous way or something, i guess?

This is the database, and the highlighted node is the value i would like to get:

Firebase数据快照返回空值。

This is my code:

            reference = FirebaseDatabase.getInstance().getReference();
            id = null;
            Query lastQuery = reference.child("Donation Request").orderByKey().limitToLast(1);
            lastQuery.addListenerForSingleValueEvent(new ValueEventListener()
            {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot)
                {
                    if (dataSnapshot.child("id").exists())
                    {
                        id = dataSnapshot.child("id").getValue().toString();
                        int index = Integer.parseInt(id) + 1;
                        id = Integer.toString(index);
                        Toast.makeText(getApplicationContext(), "It works!!!", Toast.LENGTH_SHORT).show();
                    }
                    else
                    {
                        id = "1";
                        Toast.makeText(getApplicationContext(), "It doesn't work.", Toast.LENGTH_SHORT).show();
                    }
                }
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError)
                {

                }
            });

Most appreciated if someone can help me out of this!

答案1

得分: 1

当您对Firebase数据库执行查询时,可能会得到多个结果。因此,快照包含了这些结果的列表。即使只有一个结果,快照也会包含一个结果的列表。

您的onDataChange需要通过循环遍历dataSnapshot.getChildren()来处理这个列表:

reference = FirebaseDatabase.getInstance().getReference();
id = null;
Query lastQuery = reference.child("Donation Request").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener()
{
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot)
    {
        for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
            if (snapshot.hasChild("id"))
            {
                id = snapshot.child("id").getValue(String.class);
                int index = Integer.parseInt(id) + 1;
                id = Integer.toString(index);
                Toast.makeText(getApplicationContext(), "It works!!!", Toast.LENGTH_SHORT).show();
            }
            else
            {
                id = "1";
                Toast.makeText(getApplicationContext(), "It doesn't work.", Toast.LENGTH_SHORT).show();
            }
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError)
    {
        throw databaseError.toException(); // 永远不要忽视错误。
    }
});

另外注意:

  • 任何对id的使用都需要在onDataChange内部进行,或者从其中调用。在外部,您无法保证id将被赋予您所期望的值。
  • 使用吐司(Toast)进行调试可能会变得混乱。我强烈建议使用Log.d(...)等方法,研究应用程序的logcat输出中的输出(及其顺序)。
英文:

When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.

Your onDataChange needs to handle this list by looping over dataSnapshot.getChildren()):

reference = FirebaseDatabase.getInstance().getReference();
id = null;
Query lastQuery = reference.child("Donation Request").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener()
{
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot)
    {
        for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
            if (snapshot.hasChild("id"))
            {
                id = snapshot.child("id").getValue(String.class);
                int index = Integer.parseInt(id) + 1;
                id = Integer.toString(index);
                Toast.makeText(getApplicationContext(), "It works!!!", Toast.LENGTH_SHORT).show();
            }
            else
            {
                id = "1";
                Toast.makeText(getApplicationContext(), "It doesn't work.", Toast.LENGTH_SHORT).show();
            }
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError)
    {
        throw databaseError.toException(); // never ignore errors.
    }
});

A few more notes:

  • Any use of id needs to happen inside onDataChange, or be called from there. Outside of that, you won't have any guarantees that id will have been assigned the value you expect.
  • Using toasts for debugging is bound to become confusing. I highly recommend using Log.d(...) and friends, and studying the output (and its order) in the logcat output of your app.

huangapple
  • 本文由 发表于 2020年5月30日 12:01:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/62097658.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定