在Android中使用firebase按ID查找对象的方法

在Android中使用firebase按ID查找对象的方法,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,好吧,我想创建这个方法,但是由于您无法从listener的方法返回,所以我无法找到在firebase找到它时为用户提供的方法: public static User findByID(@NonNegative final int id) { getDatabase().orderByChild("id") .equalTo(id) .limitToFirst(1) .addChildEventListener(new

好吧,我想创建这个方法,但是由于您无法从listener的方法返回,所以我无法找到在firebase找到它时为用户提供的方法:

public static User findByID(@NonNegative final int id) {
    getDatabase().orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    dataSnapshot.getValue(User.class);    // this one must be returned
                }

                @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
                @Override public void onChildRemoved(DataSnapshot dataSnapshot) {}
                @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
                @Override public void onCancelled(DatabaseError databaseError) {}
            });
}

创建一个变量来接收值和返回也不起作用,因为firebase需要花费一些时间来查找用户。

数据检索在firebase中是异步的,因此您无法返回。我认为有两种方法可以克服你面临的问题

第一条路

如果应该在findById所在的同一类中的某个位置返回数据,则可以执行以下操作:

class A {

    private TextView nameTextView;

    ...

    public void findById(@NonNegative int id) {
        userRef().orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    onUserRetrieved(user);
                }
                ...
            });
    }

    private void onUserRetrived(User user) {
        // Now you can do whatever you want with the "user"
        // For instance, update name field in the layout...
        nameTextView.setText(user.getName);
        ...
    }
}
class Caller {

    ...

    private void someFunction() {
        ...
        String userId = 1; // Get user id somehow
        DatabaseUtil.findUserById(userId, new DatabaseUtil.Listener() {
            @Override
            public void onUserRetrieved(User user) {
                // Now you can do whatever you want with the "user"
            }
        });
        ...
    }
}
class DatabaseUtil {

    public static void findUserById(@NonNegative int id, Listener listener) {
        FirebaseDatabase.getInstance().getreference("user")
            .orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    listener.onUserRetrieved(user);
                }
                ...
            });
    }

    interface Listener {
        void onUserRetrieved(User user);
    }
}
第二条路

如果需要通知另一个类的实例,可以将侦听器作为参数传递给函数,然后调用该侦听器中的方法作为通知调用方的方式。示例调用方如下所示:

class A {

    private TextView nameTextView;

    ...

    public void findById(@NonNegative int id) {
        userRef().orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    onUserRetrieved(user);
                }
                ...
            });
    }

    private void onUserRetrived(User user) {
        // Now you can do whatever you want with the "user"
        // For instance, update name field in the layout...
        nameTextView.setText(user.getName);
        ...
    }
}
class Caller {

    ...

    private void someFunction() {
        ...
        String userId = 1; // Get user id somehow
        DatabaseUtil.findUserById(userId, new DatabaseUtil.Listener() {
            @Override
            public void onUserRetrieved(User user) {
                // Now you can do whatever you want with the "user"
            }
        });
        ...
    }
}
class DatabaseUtil {

    public static void findUserById(@NonNegative int id, Listener listener) {
        FirebaseDatabase.getInstance().getreference("user")
            .orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    listener.onUserRetrieved(user);
                }
                ...
            });
    }

    interface Listener {
        void onUserRetrieved(User user);
    }
}
鉴于您的静态函数可能位于一个类中,如下所示:

class A {

    private TextView nameTextView;

    ...

    public void findById(@NonNegative int id) {
        userRef().orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    onUserRetrieved(user);
                }
                ...
            });
    }

    private void onUserRetrived(User user) {
        // Now you can do whatever you want with the "user"
        // For instance, update name field in the layout...
        nameTextView.setText(user.getName);
        ...
    }
}
class Caller {

    ...

    private void someFunction() {
        ...
        String userId = 1; // Get user id somehow
        DatabaseUtil.findUserById(userId, new DatabaseUtil.Listener() {
            @Override
            public void onUserRetrieved(User user) {
                // Now you can do whatever you want with the "user"
            }
        });
        ...
    }
}
class DatabaseUtil {

    public static void findUserById(@NonNegative int id, Listener listener) {
        FirebaseDatabase.getInstance().getreference("user")
            .orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    listener.onUserRetrieved(user);
                }
                ...
            });
    }

    interface Listener {
        void onUserRetrieved(User user);
    }
}

数据检索在Firebase中是异步的,因此无法返回。我认为有两种方法可以克服你面临的问题

第一条路

如果应该在findById所在的同一类中的某个位置返回数据,则可以执行以下操作:

class A {

    private TextView nameTextView;

    ...

    public void findById(@NonNegative int id) {
        userRef().orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    onUserRetrieved(user);
                }
                ...
            });
    }

    private void onUserRetrived(User user) {
        // Now you can do whatever you want with the "user"
        // For instance, update name field in the layout...
        nameTextView.setText(user.getName);
        ...
    }
}
class Caller {

    ...

    private void someFunction() {
        ...
        String userId = 1; // Get user id somehow
        DatabaseUtil.findUserById(userId, new DatabaseUtil.Listener() {
            @Override
            public void onUserRetrieved(User user) {
                // Now you can do whatever you want with the "user"
            }
        });
        ...
    }
}
class DatabaseUtil {

    public static void findUserById(@NonNegative int id, Listener listener) {
        FirebaseDatabase.getInstance().getreference("user")
            .orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    listener.onUserRetrieved(user);
                }
                ...
            });
    }

    interface Listener {
        void onUserRetrieved(User user);
    }
}
第二条路

如果需要通知另一个类的实例,可以将侦听器作为参数传递给函数,然后调用该侦听器中的方法作为通知调用方的方式。示例调用方如下所示:

class A {

    private TextView nameTextView;

    ...

    public void findById(@NonNegative int id) {
        userRef().orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    onUserRetrieved(user);
                }
                ...
            });
    }

    private void onUserRetrived(User user) {
        // Now you can do whatever you want with the "user"
        // For instance, update name field in the layout...
        nameTextView.setText(user.getName);
        ...
    }
}
class Caller {

    ...

    private void someFunction() {
        ...
        String userId = 1; // Get user id somehow
        DatabaseUtil.findUserById(userId, new DatabaseUtil.Listener() {
            @Override
            public void onUserRetrieved(User user) {
                // Now you can do whatever you want with the "user"
            }
        });
        ...
    }
}
class DatabaseUtil {

    public static void findUserById(@NonNegative int id, Listener listener) {
        FirebaseDatabase.getInstance().getreference("user")
            .orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    listener.onUserRetrieved(user);
                }
                ...
            });
    }

    interface Listener {
        void onUserRetrieved(User user);
    }
}
鉴于您的静态函数可能位于一个类中,如下所示:

class A {

    private TextView nameTextView;

    ...

    public void findById(@NonNegative int id) {
        userRef().orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    onUserRetrieved(user);
                }
                ...
            });
    }

    private void onUserRetrived(User user) {
        // Now you can do whatever you want with the "user"
        // For instance, update name field in the layout...
        nameTextView.setText(user.getName);
        ...
    }
}
class Caller {

    ...

    private void someFunction() {
        ...
        String userId = 1; // Get user id somehow
        DatabaseUtil.findUserById(userId, new DatabaseUtil.Listener() {
            @Override
            public void onUserRetrieved(User user) {
                // Now you can do whatever you want with the "user"
            }
        });
        ...
    }
}
class DatabaseUtil {

    public static void findUserById(@NonNegative int id, Listener listener) {
        FirebaseDatabase.getInstance().getreference("user")
            .orderByChild("id")
            .equalTo(id)
            .limitToFirst(1)
            .addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    User user = dataSnapshot.getValue(User.class);
                    listener.onUserRetrieved(user);
                }
                ...
            });
    }

    interface Listener {
        void onUserRetrieved(User user);
    }
}

您无法返回异步对象,因此需要将EventListener传递给您创建的函数,当你找到用户时调用它。你所做的与我开始使用Firebase时所做的非常相似–基本上是尝试创建同步方法来检索数据,与使用传统数据库类似。不幸的是,这并不是Firebase的工作方式遗憾的是,Firebase的异步特性是其工作方式的固有特性,您需要构建应用程序的行为,有时会有点麻烦。您无法返回异步对象,因此您需要将EventListener传递给您创建的函数,当你找到用户时调用它。你所做的与我开始使用Firebase时所做的非常相似–基本上是尝试创建同步方法来检索数据,与使用传统数据库类似。不幸的是,这不是Firebase的工作方式可悲的是,Firebase的异步特性是其工作方式的固有特性,你需要围绕着它来构建你的应用程序的行为,这有时会有点麻烦。这对我来说有点抽象。你能举个例子吗?你打算在哪里使用你的FunByID方法?让我们考虑一下我的用户ID,想让他的名字显示在PrraveActudio上。哦,我明白你的意思了。第二种方法很好用。谢谢你的耐心!hi@mehmad有任何方法可以根据所选id查询数据。使用loopIt对我来说有点抽象。你能举个例子吗?你打算在哪里使用你的FunByID方法?让我们考虑一下我的用户ID,想让他的名字显示在PrraveActudio上。哦,我明白你的意思了。第二种方法很好用。谢谢你的耐心!hi@mehmad有任何方法可以根据所选id查询数据。使用循环