【问题标题】:How to use addValueEventListener in a first time for Android如何在 Android 上首次使用 addValueEventListener
【发布时间】:2018-05-30 15:08:20
【问题描述】:

Android 的 Firebase 数据库 api 非常令人困惑。

我想更新json 对象的某些部分,但我不能。这是firebase数据库。

首先用户创建词汇,遵循这段代码

    /* reference of /vocabulary/{user_id}/*/
    final DatabaseReference vocabularyRef = FBDatabaseReference.getAllVocabulary(user);

    if (!TextUtils.isEmpty(oldName)){
        // if vocabulary renamed remove preview
        vocabularyRef.child(oldName).removeValue();
    }
    // set user vocabulary
    vocabularyRef.child(String.valueOf(userVocabulary.name())).
            setValue(new FBVocabulary(userVocabulary), completionListener);

如果词汇表已成功创建,用户可以将单词添加到其中。 但是添加单词后,用户可以修改词汇表namecolor等。那段时间我丢失了所有单词,因为词汇表对象已经重新创建。

根据 Firebase doc for update a child 我应该 addListenerForSingleValueEventaddValueEventListener 当我使用addListenerForSingleValueEvent 而不是预览代码时,用户无法创建词汇表。

如果尚未创建引用,则在编写的 firebase 文档中,快照对象为空。

    /* reference of /vocabulary/{user_id}/vocabulary3/ */
    final DatabaseReference vocabularyRef = FBDatabaseReference.getAllVocabulary(user).child("vocabulary3");
    vocabularyRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Object value = dataSnapshot.getValue();
            if (value == null){
                dataSnapshot.getRef().setValue(new FBVocabulary(userVocabulary), completionListener);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

在这种情况下,每次调用onCancelled(DatabaseError databaseError) 异常:权限被拒绝。据我了解是因为引用是null

  1. 我可以检查引用是否存在吗?然后更新数据。

  2. 如何在第一次使用addValueEventListener

【问题讨论】:

  • 您在使用监听器时尝试的代码是什么?你还想更新什么?如果您正在更新 vocabulary1 并且 words 节点在其中,那么是的,它将被覆盖
  • @Peter Haddad 我要更新词汇数据,没有词,用户词不能更改

标签: java android json firebase firebase-realtime-database


【解决方案1】:

试试这个:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("vocabulary1");
ref.child("color").setValue(new_value);
ref.child("id").setValue(new_value);
ref.child("footercolor").setValue(new_value);
ref.child("headercolor").setValue(new_value);
//and so on..

您可以这样做,从而在不更改word 节点的值的情况下更新节点下的值。

要检查它是否存在,请这样做:

DatabaseReference refs=FirebaseDatabase.getInstance().getReference().child("vocabulary").child("key_here").child("vocabulary1");
 refs.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
               if(dataSnapshot.exists()){
                 //dont do anything
                }
                else{
                     refs.child("color").setValue(new_value);
                      //so on
                    } 
                  }
               });

【讨论】:

  • 我同意彼得,这是正确的,但用户可以重命名密钥,我应该以任何方式获取对象快照并更新。但在这种情况下,用户不能创建第一个。没有任何方法可以检查引用是否存在?
  • 什么意思?您希望用户更新vocabulary 下的随机密钥还是其他密钥?你想让他更新这个kZPOUKw87nQm7nJTbMo0gmzaoGg1
  • vocabulary1 是词汇的名称。用户可以修改和设置其他名称
  • 是的,这是行不通的,因为如果你改变了vocabulary1,那么里面的所有东西也会改变(所以单词也会改变)
  • 这就是为什么我应该从参考中获取数据的原因,在 JS api 中有某种 api 来获取数据,但是对于我找不到的 android 或者它还不可用
【解决方案2】:

我找到了解决方案,那是因为数据库规则。 取决于这一行

".read"  : "auth != null && $uid == auth.uid && data.exists()"

如果 data.exists() 规则在每次调用 addValueEventListener->onCancelled 方法时添加,而数据尚未创建。

虽然没有 data.exists() 规则,但 addValueEventListener 返回对象 snapshot 并且它为空。然后我可以创建 if is null,或者更新 if is not null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    相关资源
    最近更新 更多