如何跳过Firebase数据库中的初始OnChildAdded事件触发

时间:2016-09-13 14:56:05

标签: java spring firebase firebase-realtime-database

我的Firebase数据库中有一个用户子树,它保留该用户的基本用户信息和关注/关注者,此子树的结构如下:

"users": {
  "userId-1": { 
    "userName": "Namey McNameface",

    "following": {
      "followingId-1": true,
      "followingId-2": true,
      .
      .
    },
    "followers": {
      "followerId-1": true,
      "followerId-2": true,
      .
      .
    }
  },
  "userId-2": {},
  "userId-3": {},
  .
  .
}

我想在有人开始关注他/她时向用户的手机发送通知。 在我自己的服务器中,我听取了粉丝的子树。添加子项后,用户将看到通知。 问题是,在某些时候我需要部署我的服务器的下一个版本,当我这样做时,OnChildAdded事件将触发所有孩子(粉丝),并且所有用户都会看到有关其关注者的错误通知开始跟着他们。

我可以将发送通知信息存储在我的数据库中以解决此问题,但这对我来说将是一项耗时的工作。

另一种方法是,如果可以在Firebase数据库中使用,我可以跳过OnChildAdded事件的初始触发。

提前谢谢。

修改

我正在为我的服务器使用Java和Spring。 这是我的FirebaseService。我正在创建一个UserListener并开始监听所有用户。

@Service
public class FirebaseService {
    public FirebaseService() {
        UserListener userListener = new UserListener();
        FirebaseDatabase.getInstance().getReference(Tag.USERS).addChildEventListener(userListener);
    }
}

这是UserListener。它会为每个用户创建一个FollowerListener来监听followers子树。

public class UserListener implements ChildEventListener {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        String userId = dataSnapshot.getKey();
        FollowerListener followerListener = new FollowerListener(userId);
        FirebaseDatabase.getInstance().getReference(Tag.USERS).child(userId).child(Tag.FOLLOWERS).addChildEventListener(followerListener);
    }

    @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) {

    }
}

这是FollowerListener。将用户标识添加到followers时,FollowerListener会发送通知。它基本上获得了跟随用户的FirebaseInstanceId和关注者用户的屏幕名称。然后发送通知。

public class FollowerListener implements ChildEventListener {
    private final String followedUserId;

    public FollowerListener(String followedUserId){
        this.followedUserId = followedUserId;
    }

    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        String followerUserId = dataSnapshot.getKey();
        FirebaseDatabase.getInstance().getReference(Tag.USERS).child(followedUserId)
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        User followedUser = dataSnapshot.getValue(User.class);

                        if(followedUser != null){
                            FirebaseDatabase.getInstance().getReference(Tag.USERS).child(followerUserId)
                                    .addListenerForSingleValueEvent(new ValueEventListener() {
                                        @Override
                                        public void onDataChange(DataSnapshot dataSnapshot) {
                                            User followerUser = dataSnapshot.getValue(User.class);

                                            if(followerUser != null){

                                                // Send notification to followed user.

                                                NotificationInfo notificationInfo = new NotificationInfo();
                                                notificationInfo.setTitle("test title");
                                                notificationInfo.setText(followerUser.getScreenName() + " seni takip etmeye başladı.");
                                                notificationInfo.setClickAction(Tag.ACTION_GO_TO_PROFILE);

                                                NotificationData data = new NotificationData();
                                                data.setUserId(followerUserId);

                                                NotificationRequestBean bean = new NotificationRequestBean();
                                                bean.setTo(followedUser.getFirebaseInstanceId());
                                                bean.setBody("test body");
                                                bean.setTitle("test title");
                                                bean.setPriority("normal");
                                                bean.setDelayWhileIdle(false);
                                                bean.setNotification(notificationInfo);
                                                bean.setData(data);

                                                AppUtils.sendNotification(bean);
                                            }
                                        }

                                        @Override
                                        public void onCancelled(DatabaseError databaseError) {

                                        }
                                    });
                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
    }

    @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) {

    }
}

问题是每当我部署服务器时,FollowerListener会附加到所有用户的followers子树。然后,最初为每个关注者触发OnChildAdded事件。它不应该在每次部署服务器时发送通知。

感谢。

1 个答案:

答案 0 :(得分:0)

我找到了一个解决这个问题的简单方法。我刚刚在名为boolean的{​​{1}}子树中添加了followers字段。所以它变成了这样:

processedByServer

"followers": { "followerId-1": { "processedByServer": true // already processed. }, "followerId-2": { "processedByServer": false // not processed yet, but will be. }, . . } 最初为processedByServer,在我在服务器中进行必要的处理(发送通知等)后,我将此值更改为false。服务器只需在此字段为true时进行处理。因此,在重新部署/重新启动服务器之后,它不再发送错误的通知。

但这个解决方案也有缺点:

  1. 我为此添加了一个额外的字段,但我认为没问题。
  2. 当服务器重新启动时,它必须检查false子树中的所有processedByServer字段,这对于服务器来说可能是一项耗时的工作。