【问题标题】:Firebase onDataChange - Value Event Listener not listening for changesFirebase onDataChange - 值事件侦听器不侦听更改
【发布时间】:2019-01-11 05:15:02
【问题描述】:

我正在尝试从如下所示的用户帐户中读取数据列表:

但是onDataChange 监听器没有被调用。

我想得到“checked”和“desc”的值;但是,当我添加如下所示的 listenForSingleValueEvent 侦听器时,不会调用 onDataChange 并且我不会检索值。

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("accounts")
            .child(uid).child("user_t").child(item_id);
//"user_t" has been shortened for this post

    databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.i(TAG, "onDataChange: Getting single data");

            String name = (String) dataSnapshot.child("checked").getValue();
            String date = (String) dataSnapshot.child("desc").getValue();
        }
    //on Cancel etc..
    };

即使只有:

String name = (String) dataSnapshot.child("checked").getValue();"

onDataChange 内部仍然不会触发。根据我从 Firebase 文档中读到的内容,我必须使用侦听器来读取数据。

我在应用程序的另一部分有类似的代码,它或多或少与上述代码应该做的事情相同,而且效果很好。

我最近在使用 Firebase 时遇到了很多麻烦,因此感谢您的帮助。干杯!

编辑: 更多具有相同结果的代码:

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("accounts").child(uid);
databaseReference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Log.i(TAG, "onDataChange: ");
        String name = dataSnapshot.child("name").getValue().toString();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

编辑 2: 我可以在帐户部分和项目部分中创建一个键并为其设置一个值,但它会调用onDataChange 函数。我已经能够绕过这个问题;但是,一旦其调用类被解构并抛出 NullPointerException,因为类级变量不再存在,侦听器就会被调用。

编辑 3 - 整个班级:

这是一个不同的课程,但我遇到了完全相同的问题。

public class StartActivity extends AppCompatActivity {

//firebase variables
private FirebaseAuth mAuth;
private FirebaseUser currentUser;
private FirebaseDatabase database;
private DatabaseReference userReference;
private String uid;
private String accountType;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    //set splash theme
    setTheme(R.style.SplashStyle);
    super.onCreate(savedInstanceState);

    //get an authentication instance
    mAuth = FirebaseAuth.getInstance();
    //get user database
    database = FirebaseDatabase.getInstance();
    userReference = database.getReference(ACCOUNTS);


    //get the user and check if logged in
    currentUser = mAuth.getCurrentUser();
    if (currentUser != null){
        uid = currentUser.getUid();
        getAccountType();

        //open the dashboard
        openDashboard();
    }else{
        openLogin();
    }

    finish();
}

private void openDashboard() {
    Intent dashboard = new Intent(this,Dashboard.class);

    dashboard.putExtra(String_Values.ACCOUNT_TYPE,accountType);
    dashboard.putExtra(String_Values.ACCOUNT_UID,uid);

    startActivity(dashboard);
    finish();

}

private void openLogin(){
    Intent loginIntent = new Intent(this,Login.class);
    startActivity(loginIntent);
}


private void getAccountType(){
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference databaseReference = database.getReference(ACCOUNTS).child(uid);
    Log.i(String_Values.TAG, "uid: " + uid);
    databaseReference.addListenerForSingleValueEvent(get_account_listener);
}

ValueEventListener get_account_listener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        accountType = dataSnapshot.child(TYPE).getValue().toString();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.i(String_Values.TAG, "onCancelled: " + databaseError.getMessage());
    }
};

}

【问题讨论】:

  • 你能检查一下uid是否和你的数据库一样吗?
  • 是的,值是一样的。

标签: java android firebase firebase-realtime-database


【解决方案1】:

您无法获得任何东西,因为您没有循环获取 DataSnapshot 对象中的子项。所以要解决这个问题,请使用以下代码行:

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("accounts")
        .child(uid).child("user_t");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String name = ds.child("checked").getValue(String.class);
            String date = ds.child("desc").getValue(String.class);
        }

    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
    }
};

如果仍然没有触发,请检查 logcat 以查看 databaseError.getMessage() 是否返回。

【讨论】:

  • 如果您硬编码参考中的值(uiduser_t 等)会发生什么,它是否有效?
  • 是的,当我对值进行硬编码时,也会发生同样的事情。我实际上可以在那个人的帐户中创建和设置值,但无法从中读取任何内容?
  • 您是否对数据库结构进行了圆顶更改?你能分享你全班的代码吗?
  • 结构没有变化,但我可以将键和值添加到我想要检索值的确切位置。我添加了一个我遇到问题的课程。
  • accounts 节点下应该有uid,对吧?但我在您的代码中看到了与test 相关的内容。这怎么可能?可以分享一下真实的数据库结构吗?
【解决方案2】:

感谢Alex Mamo 的回答here。完美解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多