Java 如何仅在Firebase数据库发生更改时调用通知?

Java 如何仅在Firebase数据库发生更改时调用通知?,java,firebase,firebase-realtime-database,Java,Firebase,Firebase Realtime Database,作为标题,我想做的只是当数据库发生更改时才运行通知,但问题是当我运行应用程序时,即使数据没有更改,也会出现通知 这是我的密码: public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v= inflater.inflate(R.layout.main,container

作为标题,我想做的只是当数据库发生更改时才运行通知,但问题是当我运行应用程序时,即使数据没有更改,也会出现通知 这是我的密码:

 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v= inflater.inflate(R.layout.main,container,false);

        result= (TextView) v.findViewById(R.id.textView3);


        notificationmanager = NotificationManagerCompat.from(ct.getcontext());
        if (user != null) {

            ref.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    if (dataSnapshot.exists()) {
                        String post = dataSnapshot.getValue(String.class);
                        result.setText(post);

                        Notification notification = new NotificationCompat.Builder(ct.getcontext(), CHANNEL_1_ID)
                                .setSmallIcon(R.drawable.ic_launcher_foreground)
                                .setContentTitle(post)
                                .setContentText("test")
                                .setPriority(NotificationCompat.PRIORITY_HIGH)
                                .setCategory(NotificationCompat.CATEGORY_EVENT)
                                .setDefaults(Notification.DEFAULT_ALL)
                                .build();
                        notificationmanager.notify(2,notification);



                    }

                }

                @Override
                public void onCancelled(DatabaseError error) {

                }
            });

        }
        else
        {
            Toast.makeText(getActivity(),"not yet login",Toast.LENGTH_LONG).show();
        }


        return v;
    }

您需要使用文档中的
addValueEventListener()

public-ValueEventListener-addValueEventListener(ValueEventListener-listener)

在此位置添加数据更改的侦听器。每次数据更改时,都会使用数据的不可变快照调用侦听器


使用
addValueEventListener
,每当数据库发生更改时,就会触发该更改。

将该值保存在本地首选项中,然后在下一次更改时,通过与以前保存的值进行比较,验证该值是否确实更改。

来自@mikasaloli的解释,我怀疑问题更多地在于firebase RTDB(实时数据库)/Firestore功能和错误侦听器的混合方式

第一个问题是,firebase RTDB/firestore默认情况下会保留您在手机上访问的引用(不是所有引用)的本地缓存副本。从他们的文件中,我引用: 异步侦听器:存储在Firebase实时数据库中的数据是通过将异步侦听器附加到数据库引用来检索的。对于数据的初始状态,侦听器会被触发一次,并且在数据更改时会再次触发。事件侦听器可能会接收多个不同的数据。Java、Nod支持这种数据检索模式e、 js和Python管理SDK。” 你需要做的是在应用启动后第一次读取数据时绕过本地缓存。

第二个问题与前面提到的一样,addListenerForSingleValueEvent只会触发一次。因此,假设您第一次收到通知更改,您的侦听器将自动注销自身,这意味着您将不会收到后续onDataChange事件

现在,根据前面几段推测,上述代码的问题是: 它为单值事件附加一个侦听器。然后,将使用数据的本地(缓存)版本触发,该版本强制不是服务器数据库的最新状态(如果应用程序处于脱机状态,而某些更改发生在联机状态)。但是,在附加此侦听器时,它会被数据的本地版本触发,并随后注销自身。这意味着,上面的代码最多会被触发一次,并且在连接期间可能永远不会被触发


我的建议是,绕过本地缓存,使用addValueEventListener。

我的道歉我删除了它第一次调用firebase也可以像
onDataChange
那样工作。您可以将对firebase的调用更改为
addChildEventListener
,您将得到更多的回调,如
onChildChanged
。请注意,您需要更改对的引用。此侦听器将只为您提供一次所用引用中的值的datasnapshot。不管某个值是否已更改,侦听器也将始终使用当前值启动,因此OP需要过滤掉该值,例如,通过在本地首选项中跟踪它作为。