i try to set a boolean value in my Firebase Realtime Database but when i run set Value in a addValueListener function it starts to change value forever and seems like onCreateView starts in a loop. Here is my code:
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) {
}
});
}
I want when button is cliccked, a control of boolean value in my database and if it is true, so set it to false and if it is false, set it to true. When i click the button, the value change ever from false to true and true to false and it never stops.
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
It's because you're listening for changes to /Users/$uid
and then writing a change in there.
The simplest solution is to use a single-value event listener:
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
}
});