【问题标题】:Firebase get Value and change/update itFirebase 获取价值并更改/更新它
【发布时间】:2018-10-12 08:18:53
【问题描述】:

我之前问过几乎相同的问题。但答案不是那么好或不够好。我想重新开始,现在我有很多问题。

这是帖子。

Making a database-voting app

所以现在我有另一个想法。

这次只有一个值计票,但应用程序并没有得到值“count”的实际数量。

这是我的代码:

database = FirebaseDatabase.getInstance();
names= database.getReference("Test");

final Name name = new Name(txtName.getText().toString(), score);
names.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull final DataSnapshot dataSnapshot) {
            if (dataSnapshot.child(name.getName()).exists()) {
                up.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        names.addValueEventListener(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                score = dataSnapshot.child("Test").child("Name").getValue(long.class);
                                score += 1;
                                final Name name = new Name(txtName.getText().toString(), score);
                                try {
                                    names.child(name.getName()).setValue(name);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {
                            }
                        });

                        Toast.makeText(Result.this, "Thank you for voting", Toast.LENGTH_SHORT).show();

                        Intent homeIntent3 = new Intent(Result.this, StartActivity.class);
                        startActivity(homeIntent3);
                    }
                });

 

这是数据库

因此,如果该名称不存在,我可以轻松添加得分 = 1 或得分 = -1 的赞成/反对票。

但是如果名字存在的话,改变分数值就有问题了。

应用程序因以下错误而崩溃

java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
                  at user.prof.name.Activities.Result$1$1$1.onDataChange(Result.java:80)
                  at com.google.firebase.database.obfuscated.zzap.zza(com.google.firebase:firebase-database@@16.0.3:75)
                  at com.google.firebase.database.obfuscated.zzca.zza(com.google.firebase:firebase-database@@16.0.3:63)
                  at com.google.firebase.database.obfuscated.zzcd$1.run(com.google.firebase:firebase-database@@16.0.3:55)
                  at android.os.Handler.handleCallback(Handler.java:789)
                  at android.os.Handler.dispatchMessage(Handler.java:98)
                  at android.os.Looper.loop(Looper.java:251)
                  at android.app.ActivityThread.main(ActivityThread.java:6589)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

这是代码中的错误行

score = dataSnapshot.child("Test").child("Name").getValue(long.class);

我不是数据库编程方面的专家,但有什么问题? 找错孩子了?

我还尝试将“分数”保存为字符串并将其解析为长值。但这也行不通。

【问题讨论】:

  • 我看到的第一件事是Name 本身并不是一个属性,而且您还有一个单独的节点来存储实际值。我会做这样的代码:score = dataSnapshot.child("Test").child("Name1").child("Name1").getValue(String.class);
  • 谢谢。但是有了这个我得到了同样的错误

标签: java android firebase firebase-realtime-database


【解决方案1】:

您什么也得不到,因为您的 Name 属性名称在每个孩子中都是不同的。为了解决这个问题,你应该在每个孩子下面有相同的名字,如下所示:

Firebase-root
  |
  --- test
       |
       --- Name1
       |     |
       |     --- name: "Name1"
       |     |
       |     --- score: 0
       |
       --- Name2
             |
             --- name: "Name2"
             |
             --- score: 15

看,name 属性的名称现在总是name不是 name1、name2 等等。

要在所有对象中获取score 属性的值,请使用以下代码行:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("test").orderByChild("name");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            long score = ds.child("score").getValue(Long.class);
            Log.d(TAG, "Score: " + score);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage());
    }
};
query.addListenerForSingleValueEvent(valueEventListener);

您的 logcat 中的输出将是:

Score: 0
Score: 15

还请注意,我已传递给 getValue(Long.class)Long 类,而不是原始 long。

编辑:

要编辑单个条目,您应该使用以下代码行:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Map<String, Object> map = new HashMap<>();
map.put("score", 5);
rootRef.child("test").child("Name1").updateChildren(map);

第一个对象中的score 属性将从0 更改为5。如果您认为您的 score 属性将在多用户环境中更新,那么您应该使用 FirebaseTransactions,正如我在此 post 中的回答所解释的那样。

【讨论】:

  • 谢谢@Alex Mamo。我得到了整个列表,我可以增加所有列表并更改分数值,但我如何只编辑一个条目?我不明白......所以如果 Name1 已经存在,我怎样才能只增加那个条目?我已经尝试了一些东西,但没有任何效果......
  • 对不起。不幸的是,这个问题还没有得到 100% 的回答。如果我现在接受答案,那么不幸的是,没有人再帮助我了。我已经编辑了我对您的回答的第一个答案。
  • 我看到了编辑后的评论。因此,如果您想编辑单个条目,请查看我更新的答案。现在可以了吗?
  • 非常感谢!这是正确的方法。我只有两个错误。我怎样才能得到分数的实际值?如果我要添加score--; map.put("count", score);,那么它总是从 0 开始并倒数。当我添加score++; 时,它的计数无限高。一个for循环也算到无穷大
  • 很高兴听到这个消息,不客气,汉斯! “我怎样才能得到分数的实际值?”您应该为此发布另一个新问题,以便我和其他用户可以帮助您。
猜你喜欢
  • 2019-01-24
  • 1970-01-01
  • 2017-09-12
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多