【问题标题】:Android Studio firebase database wait for read before adding new valuesAndroid Studio firebase 数据库在添加新值之前等待读取
【发布时间】:2017-03-05 00:19:22
【问题描述】:

我有一个存储用户的数据库,我想在添加新用户之前检查用户是否存在,这样我就不会覆盖。

我有一个函数,它遍历数据库记录并在找到或未找到用户时返回一个布尔值。

public boolean checkUserExists(final String emailAddress, final String emailDomain){
    DatabaseReference myRef = database.getReference("Users");

    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot mydata : dataSnapshot.getChildren()){
                User user = mydata.getValue(User.class);

                if (user.getEmailAddress().equals(emailAddress) &&
                        user.getEmailDomain().equals(emailDomain)){
                    userExists = true;
                    break;
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    return userExists;
}

我目前尝试进行检查的方式是这样的:

if (!(registerRepo.checkUserExists(emailAddress, emailDomain))){
                User user = new User(firsName, lastName, emailAddress, emailDomain);
                registerRepo.writeUser(user);
            } else {
                Toast toast = Toast.makeText(getBaseContext(), "User exists", Toast.LENGTH_SHORT);
                toast.show();
            }

问题在于它不等待读取并继续创建新记录(我正在使用推送,因此它在新的推送 ID 下创建相同的记录)。我已经看到firebase有一个叫做事务处理程序的东西,我认为这是我需要使用的,但是文档没有帮助我,我看过其他人在这里问同样的问题,但不能请找出一个解决方案,如果你能解释一下如何做到这一点,而不是将我重定向到其他问题,我将不胜感激。

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    Firebase 请求是异步的。

    因此,如果您想在从数据库中获取结果后执行一些代码,则需要在 checkUserExists 中添加回调。

    例如:

    public interface OnCheckUserExist {
        void exist();
        void notExist();
    }
    
    registerRepo.checkUserExists(emailAddress, emailDomain, new OnCheckUserExist(){
       @Override
       public void exist(){
           Toast toast = Toast.makeText(getBaseContext(), "User exists",Toast.LENGTH_SHORT);
           toast.show();
       }
       @Override
       public void notExist(){
           User user = new User(firsName, lastName, emailAddress, emailDomain);
           registerRepo.writeUser(user);
       }
    })
    
    
    public void checkUserExists(final String emailAddress, final String emailDomain, OnCheckUserExist onCheckUserExist){
        DatabaseReference myRef = database.getReference("Users");
        myRef.addValueEventListener(new ValueEventListener() {
            boolean userExist;
    
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot mydata : dataSnapshot.getChildren()){
                    User user = mydata.getValue(User.class);
    
                    if (user.getEmailAddress().equals(emailAddress) &&
                            user.getEmailDomain().equals(emailDomain)){
                        onCheckUserExist.exist();
                        userExist = true;
                        break;
                    }
                }
                if (!userExist){
                  onCheckUserExist.notExist();
                }
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
    
            }
        });
    }
    

    【讨论】:

    • 那个回调是什么?我知道对于常规 asyncTasks 是 onPostExecute。这里也一样吗?我在哪里添加它?
    • 我试过这个方法,它说 .exist() 和 .notExist() 是非静态方法,不能从静态内容中引用它们。如果我将 exists() 和 notExist() 设为静态,则表示“此语言级别不支持扩展方法”。请帮忙
    • 您必须创建 接口 OnCheckUserExist 才能创建监听器。
    • 我确实在 RegisterRepo 类中创建了它。是不是找错地方了?
    • 不应该可以...你需要添加一个匿名类来创建监听器或直接实现这个接口。
    【解决方案2】:

    您需要像这样将代码放在 onDataChange 中

    public boolean checkUserExists(final String emailAddress, final String emailDomain){
        DatabaseReference myRef = database.getReference("Users");
    
        myRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot mydata : dataSnapshot.getChildren()){
                    User user = mydata.getValue(User.class);
    
                    if (user.getEmailAddress().equals(emailAddress) &&
                            user.getEmailDomain().equals(emailDomain)){
                        userExists = true;
                        break;
                    }
                }
                if (userExists) {
                    User user = new User(firsName, lastName, emailAddress, emailDomain);
                    registerRepo.writeUser(user);
                } else {
                    Toast toast = Toast.makeText(getBaseContext(), "User exists", Toast.LENGTH_SHORT);
                    toast.show();
                }
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
    
            }
        });
    
        return userExists;
    }
    

    虽然我建议您通过创建单独的函数来重构这个。 :)

    【讨论】:

    • 我想使用 4 层原则将它们分开,这样做意味着将数据访问层与应用程序逻辑层结合起来。
    猜你喜欢
    • 2021-07-12
    • 2017-07-20
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    相关资源
    最近更新 更多