DatabaseReference setValue 像循环一样工作

DatabaseReference setValue woks like in a loop

我尝试在我的 Firebase 实时数据库中设置一个布尔值,但是当我 运行 在 addValueListener 函数中设置值时,它开始永远更改值,并且 onCreateView 似乎在循环中开始。 这是我的代码:

private static DatabaseReference myref;

    public static home_fragment newInstance(String param1, String param2) {
        home_fragment fragment = new home_fragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        this.container = container;
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        myref = FirebaseDatabase.getInstance("https://piazzodivale-default-rtdb.europe-west1.firebasedatabase.app").getReference("Users");
         nome = "";
         getNome(); 
        present_button = view.findViewById(R.id.presenza);
        present_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myref.child(userID).addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        if (snapshot.child("presente").getValue(Boolean.class) == true){
                            myref.child(userID).child("presente").setValue(false);

                        } else {
                            myref.child(userID).child("presente").setValue(true);
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {

                    }
                });


            }
        });



        return view;

    }
    @Override
    public void onStart() {
        super.onStart();
        Log.d("Presente", String.valueOf(presente));

    }
private void getNome(){ //ottine il nome dell'utente attraverso il db e lo salva nella variabile nome
        userMap.clear();

        myref.child(userID).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                userMap.put("Nome",  snapshot.child("Nome").getValue(String.class));
                Log.d("Nome", userMap.get("Nome").toString());
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });


    }


我想要当按钮被点击时,我的数据库中的一个布尔值控件,如果它是真的,那么将它设置为假,如果它是假的,将它设置为真。当我单击按钮时,值会从 false 变为 true,然后从 true 变为 false,并且它永远不会停止。

2021-03-12 00:53:18.504 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:18.505 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.501 19301-19301/com.example.stanzetta I/chatty: uid=10165(com.example.stanzetta) identical 638 lines
2021-03-12 00:53:19.502 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.505 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.898 19301-19301/com.example.stanzetta I/chatty: uid=10165(com.example.stanzetta) identical 269 lines
2021-03-12 00:53:19.899 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.900 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:20.505 19301-19301/com.example.stanzetta I/chatty: uid=10165(com.example.stanzetta) identical 365 lines
2021-03-12 00:53:20.507 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:20.509 19301-19301/com.example.stanzetta D/Nome: Valerio

这是因为您正在监听 /Users/$uid 的更改,然后在其中写入更改。

最简单的解决方案是使用单值事件侦听器:

myref.child(userID).addListenerForValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        if (snapshot.child("presente").getValue(Boolean.class) == true){
            myref.child(userID).child("presente").setValue(false);

        } else {
            myref.child(userID).child("presente").setValue(true);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
       throw error.toException(); // never ignore errors
    }
});