Java 拥有大量childEventListeners是一种好的做法吗?

Java 拥有大量childEventListeners是一种好的做法吗?,java,android,firebase,firebase-realtime-database,geofire,Java,Android,Firebase,Firebase Realtime Database,Geofire,我用firebase编写了一个应用程序,用户可以通过GeoFire显示周围环境中的事件。Geofire返回事件ID列表,然后我下载这些事件。问题是,我需要倾听这些事件中的变化。为每个事件注册childEventListener是一种好的做法吗(可以有很多,比如说100个)?还是有更好的方法 谢谢你的帮助,Honza 编辑: 事件是包含以下字段的sportEvents:标题、描述、时间、地点、签名者等。在我下载了周围环境中的活动后,我需要倾听变化,以便我可以显示谁将参加此活动(例如足球比赛)等等

我用firebase编写了一个应用程序,用户可以通过GeoFire显示周围环境中的事件。Geofire返回事件ID列表,然后我下载这些事件。问题是,我需要倾听这些事件中的变化。为每个事件注册childEventListener是一种好的做法吗(可以有很多,比如说100个)?还是有更好的方法

谢谢你的帮助,Honza

编辑:

事件是包含以下字段的sportEvents:标题、描述、时间、地点、签名者等。在我下载了周围环境中的活动后,我需要倾听变化,以便我可以显示谁将参加此活动(例如足球比赛)等等

首先,我在geofire的帮助下下载我周围地区的EventID

    private  ObservableOnSubscribe<String> suggestedEventIDSource(@NonNull LatLng userLocation, int wantedNumberOfEvents, List<String> sports){
    return (e->{
        ArrayList<String> suggestedEventIDs = new ArrayList<>();


        final GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(userLocation.latitude,userLocation.longitude),radius);

        GeoQueryEventListener geoQueryEventListener = new GeoQueryEventListener(){

            @Override
            public void onKeyEntered(String key, GeoLocation location) {
                String[] idParts = key.split(" ");
                if((sports.size() == 0 || sports.contains(idParts[0]))
                        && !(idParts[idParts.length-1]).equals(currentUser.getUid())
                        && !(Meet2SportApp.getSignedEventIDV2().contains(key))){
                    suggestedEventIDs.add(key);
                }
            }

            @Override
            public void onKeyExited(String key) {

            }

            @Override
            public void onKeyMoved(String key, GeoLocation location) {

            }

            @Override
            public void onGeoQueryReady() {
                Log.i(TAG, "onGeoQueryReady: radius - " + radius + " events in radius - " + suggestedEventIDs.size());

                if(suggestedEventIDs.size()<wantedNumberOfEvents && radius < 50f){
                    radius++;
                    e.onComplete();
                }
                else {
                    for(String eventID : suggestedEventIDs)
                         e.onNext(eventID);
                }
            }

            @Override
            public void onGeoQueryError(DatabaseError error) {

            }
        };


        geoQuery.addGeoQueryEventListener(geoQueryEventListener);
        e.setCancellable(geoQuery::removeAllListeners);
    });
}
private observeOnSubscribe suggestedEventIDSource(@NonNull LatLng userLocation,int wantedNumberOfEvents,List sports){
返回(e->{
ArrayList SuggestedEventId=新的ArrayList();
final GeoQuery GeoQuery=geoFire.QueryAtology(新地理位置(userLocation.latitude,userLocation.longitude),半径);
GeoQueryEventListener GeoQueryEventListener=新的GeoQueryEventListener(){
@凌驾
public void onKeyEntered(字符串键、地理位置){
字符串[]idParts=key.split(“”);
if((sports.size()==0 | | sports.contains(idParts[0]))
&&!(idParts[idParts.length-1]).equals(currentUser.getUid())
&&!(Meet2SportApp.GetSignedEventdV2()包含(键))){
建议的通风。添加(键);
}
}
@凌驾
public void onKeyExited(字符串键){
}
@凌驾
public void onKeyMoved(字符串键、地理位置){
}
@凌驾
公共无效onGeoQueryReady(){
Log.i(标记“onGeoQueryReady:radius-”+radius+“radius中的事件-”+suggestedEventIDs.size());
if(suggestedEvents.size(){
setErrorHandler(Functions.emptyConsumer());
Log.i(标记,“下载事件:+eventID+”在线程“+thread.currentThread().getName()上);
ValueEventListener ValueEventListener=新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
e、 onSuccess(dataSnapshot);
}
@凌驾
取消后的公共无效(FirebaseError FirebaseError){
}
};
eventDB.child(eventID).addListenerForSingleValueEvent(valueEventListener);
});
}
这很好,但当发生一些变化时,应用程序不会更新。 因此,如果我使用childEventListener而不是valueEventListener,当发生一些更改时,我会收到通知,但我将拥有大量活动的childEventListener


这是一个好的做法,还是有更好的方法?

是的,你可以有多个ChildEventListener。这是一个好的做法吗?否。你真的应该使用一个,并有一个LinkedHashMap类型的结构,这样你就可以将数据分配到某个键,然后你可以稍后再调用该键。

事件发生后具体是如何变化的?我和你一样假设事件是在一个eventID上触发的。那么他想捕获所有eventID上的所有事件吗?我假设一个
childEventListener
,只检查哪个eventID触发了事件就足够了。如果你能重新表述你的问题,那就太好了,因为目前还不清楚你在问什么。请提供事件是体育事件,例如有“足球比赛”事件创建的用户可以编辑时间或地点。当其他用户登录此事件时,它会更改numberOfSignedUsers字段等…通过该解释,您应该真正扩展您的原始问题,解释您使用的词语,向我们显示您正在使用的代码,并向我们显示您的问题的确切位置。@Ben question已更新,我希望更清楚的是:)请你给我举个例子好吗?我不知道你是怎么理解的。我可以有一个Firebase引用节点的列表或地图,我想观察(sportevents),但我不确定,我如何才能将单个childeventlistener添加到firebase中的多个节点。如果能够以某种方式完成,它将是完美的…您能否更清楚地解释此firbase过程是如何工作的?它是一个接一个地抓取每个体育赛事还是用卡盘抓取的。如果是一个接一个,您可以创建一个循环来抓取所有数据值,然后将其推入一个数据库中linkedhasmap。首先由geofire,应用程序下载事件的所有ID,例如1公里范围内的ID。然后为每个sportEvent注册singleValueEventListener(该引用可通过eventID找到)这样,我就下载了这些sportevents。如果我注册childEventListener而不是singleValueEventListener,每当firebase中的sportEvent发生变化,应用程序就会收到通知,并下载更新的sportEvent。但我注册的childEventListener的数量与给定区域中的sportevents数量相同……您应该分配e的所有ID将ach事件发送给一个侦听器,然后对获取的数据进行排序。
 private SingleOnSubscribe<DataSnapshot> sourceOfEvent(String eventID){
    return (e -> {
        RxJavaPlugins.setErrorHandler(Functions.emptyConsumer());
        Log.i(TAG, "Downloading event: " + eventID + " on thread " + Thread.currentThread().getName());
        ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                e.onSuccess(dataSnapshot);
            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {
            }
        };
        eventDB.child(eventID).addListenerForSingleValueEvent(valueEventListener);
    });
}