Firebase + Android - 通知ChildAdded - 如何只获得新孩子?

时间:2014-07-12 14:14:07

标签: android android-service firebase

我尝试在我的应用中设置Android服务,以便在Firebase参考中侦听新的Child,并在发生这种情况时抛出通知。

我遇到了问题,因为显然每个现有记录都会调用addChildEventListener onChildAdded一次,然后实际上会监听新的孩子。

this answer @kato中声明,如果addChildEventListener被调用为ref.endAt().limit(1).addChildEventListener(...),则只会获得新添加的记录。

它实际上一次只能获得一条记录(我假设limit(1))但在收听添加记录之前它仍然会获得一条记录。

这里有一些代码:

在onCreate()中初始化监听器:

@Override
public void onCreate() {
    super.onCreate();
    this.handler = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            AllowedGroup ag = dataSnapshot.getValue(AllowedGroup.class);

            postNotif("Group Added!", ag.getName());
        }
        ...rest of needed overrides, not used...

我使用AllowedGroup.class存储记录,postNotif构建并发布通知。这部分按预期工作。

然后,onStartCommand()

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    this.f = new Firebase(FIREBASE_URL).child("users").child(this.currentUserUid).child("allowedGroups");
    f.endAt().limit(1).addChildEventListener(handler);
    return START_STICKY;
}

在实际收听新添加的孩子之前,它仍会返回一个existant 记录。

我也试过按时间戳查询,如下:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    this.f = new Firebase(FIREBASE_URL).child("users").child(this.currentUserUid).child("allowedGroups");
    f.startAt(System.currentTimeMillis()).addChildEventListener(handler);
    return START_STICKY;
}

希望它只会在服务启动后获取记录集。它没有获得现有的记录,但是甚至没有新添加的孩子

修改

我还想到了首先将所有存在的记录放入内存中,并且如果onChildAdded带来的记录在先前收集的列表中不存在,则有条件地发布通知,但似乎有点像矫枉过正,并认为这可能是一种更容易(更友好的API)方式,我是对的吗?

有人能为我提供一些见解吗?我无法在官方文档或任何StackOverflow问题或教程中找到任何内容。

感谢。

3 个答案:

答案 0 :(得分:1)

如果您有字段modifiedOn,则可以将其编入索引并设置如下查询:

Query byModified = firebaseEndpoint.orderByChild("modifiedOn").startAt(lastInAppTime);

答案 1 :(得分:0)

对我而言,逻辑是有价值 - 例如“状态” - 在决定它是否真的是新的还是旧的记录之前需要进行验证然后我将“状态”设置为不同的值所以我不要下次再来吧:

@Override
        public void onChildAdded(DataSnapshot dataSnapshot, String previousChildKey) {

                if(dataSnapshot.hasChildren()) {

                    String Id = (String) dataSnapshot.child("user_id").getValue();
                    String status = (String) dataSnapshot.child("status").getValue();

                    if (Id != null && Id.equals(storedId) && status != null && status.equals("created")) {
                        Log.d("INCOMING_REQUEST", "This is for you!");
                        sessionsRef.child(dataSnapshot.getKey()).child("status").setValue("received");
                    }

                }


        }

答案 2 :(得分:0)

我通过将Firebase数据库参考节点的项目保留在列表中来解决此问题;每当触发onChildAdded(...)方法时,请检查传入的数据快照是否在您的列表中;如果没有,那就是新数据

  

要实现这一目标,您必须满足以下条件:

  1. 具有一个唯一值,该值不得在每个项目之间重复。 (当您使用.push()方法将项​​目添加到Firebase中时,很容易实现。
  2. 重写模型类的.equals()方法,以便基于此唯一值完成比较。

此处根据您的输入提供的代码段

模型类

public class AllowedGroup {

    private String id;
    public static List<AllowedGroup> sGroups;

    // reset of fields ...


    public AllowedGroup() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }


    @Override
    public boolean equals(@Nullable Object o) {

        // If the object is compared with itself then return true
        if (o == this) {
            return true;
        }

        // Check if o is an instance of AllowedGroup or not
        if (!(o instanceof AllowedGroup)) {
            return false;
        }

        // typecast o to AllowedGroup so that we can compare data members
        AllowedGroup group = (AllowedGroup) o;

        // Compare data based on the unique id
        return (group.id).equals(id);
    }

}

收听Firebase添加的节点

@Override
public void onCreate() {
    super.onCreate();
    this.handler = new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            AllowedGroup group = dataSnapshot.getValue(AllowedGroup.class);

            if (!AllowedGroup.sGroups.contains(group)) {
                // Here you'll receive only the new added values
            }

        }

        // ...rest of needed overrides, not used... 
    }

}