有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java My databaseReference的valueEventListener onDataChange方法将不会启动

在我的活动中,我从一个特定的用户那里收集并显示所有数据,这个onDataChange方法会正确地触发并完美地显示数据

final User user = new User();

     databaseReference.addValueEventListener(new ValueEventListener()
     {
         @Override
         public void onDataChange(@NonNull DataSnapshot dataSnapshot)
         {
             user.setFirstName(dataSnapshot.getValue(User.class).getFirstName());
             view_profile_firstName.setText(user.getFirstName().toString());

             user.setLastName(dataSnapshot.getValue(User.class).getLastName());
             view_profile_lastName.setText(user.getLastName().toString());

             user.setEmail(dataSnapshot.getValue(User.class).getEmail());
             view_profile_email.setText(user.getEmail().toString());

             user.setAge(dataSnapshot.getValue(User.class).getAge());
             view_profile_age.setText(Integer.toString(user.getAge()));

             user.setGender(dataSnapshot.getValue(User.class).getGender());
             view_profile_gender.setText(user.getGender());

             user.setProfileComplete(dataSnapshot.getValue(User.class).getProfileComplete());
             view_profile_profileComplete.setText(String.valueOf(user.getProfileComplete()));

         }

         @Override
         public void onCancelled(@NonNull DatabaseError databaseError)
         {

         }
     });

尽管现在我试图检查当前登录用户的profileComplete是否为真。我希望这样做的方式是,一旦用户注册了一个帐户,他的数据存储为空字符串,profileComplete设置为false。填写完所有数据并保存个人资料后,profileComplete with将设置为true。原因是,当他们关闭应用程序后重新登录时,我希望它将他们带到主屏幕,而不是通过配置文件创建重新运行他们

这就是他们使用电子邮件和密码成功登录后,我的登录活动的样子

firebaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>()
    {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task)
        {
            if (task.isSuccessful())
            {
                final User user = new User();

                Toast.makeText(MainActivity.this, "Successful login!", Toast.LENGTH_SHORT).show();

                //Dialog related to alerting the user we are logging them in
                progressDialog.cancel();

                //Check if logging in user has completed profile or not.
                databaseReference = firebaseDatabase.getReference("Users/" + firebaseAuth.getInstance().getCurrentUser().getUid());
                databaseReference.addValueEventListener(new ValueEventListener()
                {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot)
                    {
                        user.setProfileComplete(dataSnapshot.getValue(User.class).getProfileComplete());
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError)
                    {
                        Log.d("MainActivity", "COULD NOT RECIEVE PROFILECOMPLETE FROM DATABASE");
                    }
                });

                //The profileComplete method returns TRUE, so we can skip the profile creation.
                if(user.getProfileComplete())
                {
                    Intent intent = new Intent(MainActivity.this, ViewProfileActivity.class);
                    startActivity(intent);
                }

                //the profileComplete method returns FALSE, we must send the user to the profile creation.
                else
                {
                    Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
                    startActivity(intent);
                }

我在stackoverflow上浏览了大约45分钟到一个小时,查看了各种解决方案,比如尝试使用异步处理

我的假设是,因为这都是在主线程上运行的,所以onDataChange方法在用于if语句的时间内不会接收数据。虽然为了解决这个问题,我把

databaseReference.addValueEventListener(new ValueEventListener()

在while循环中,布尔变量设置为false,只有在onDataChanged()方法触发后才会设置为true。虽然这似乎从来没有发生过,所以现在我很困惑

非常感谢您的帮助,请将链接发送到我可以阅读的文档,以进一步了解与此主题相关的内容


共 (1) 个答案

  1. # 1 楼答案

    你在问题中已经描述了这个问题的原因。所以,解决这个问题的一个方法如下:

    databaseReference = firebaseDatabase.getReference("Users/" + firebaseAuth.getInstance().getCurrentUser().getUid());
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
    
            user.setProfileComplete(dataSnapshot.getValue(User.class).getProfileComplete());
    
            //The profileComplete method returns TRUE, so we can skip the profile creation.
            if(user.getProfileComplete()) {
                Intent intent = new Intent(MainActivity.this, ViewProfileActivity.class);
                startActivity(intent);
            }
    
            //the profileComplete method returns FALSE, we must send the user to the profile creation.
            else {
                Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
                startActivity(intent);
            }
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.d("MainActivity", "COULD NOT RECIEVE PROFILECOMPLETE FROM DATABASE");
        }
    });