Reputation: 1276
I have this code in an Activity called "PrincipalActivity.java"
btnSignIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String placa = edtPlaca.getText().toString().trim();
final String token = edtToken.getText().toString().trim();
if (TextUtils.isEmpty(placa)) {
Toast.makeText(getApplicationContext(), "Ingrese una Placa", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(token)) {
Toast.makeText(getApplicationContext(), "Ingrese el Token de Seguridad", Toast.LENGTH_SHORT).show();
return;
}
mapaIntent = new Intent(getApplicationContext(),MapaActivity.class);
startActivity(mapaIntent);
Toast.makeText(getApplicationContext(), "Principal", Toast.LENGTH_SHORT).show();
myRef.child("lineas").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
try{
Object valor = "";
String clave = "";
mapaIntent = new Intent(getBaseContext(),MapaActivity.class);
for (DataSnapshot lineas: dataSnapshot.getChildren()) {//navegar por lineas
for (DataSnapshot placas: lineas.getChildren()){//navegar por placas
if (placas.getKey().toString().equals(placa.trim())) {
for (DataSnapshot llave : placas.getChildren()) {//navegar por campos de cada placa
valor = llave.getValue();
clave = llave.getKey();
if (clave.equals("token")) {
if (valor.equals(token.trim())) {
Toast.makeText(getApplicationContext(), "Placa y Token correctos!!!", Toast.LENGTH_SHORT).show();
startActivityForResult(mapaIntent,123);
} else {
Toast.makeText(getApplicationContext(), "Token de Seguridad incorrecto", Toast.LENGTH_SHORT).show();
}
}
}
}
}
Toast.makeText(getApplicationContext(),"La placa no existe",Toast.LENGTH_SHORT).show();
}
}catch (Exception ex){
Toast.makeText(getApplicationContext(),"error leyendo",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Well, as you can see the code is part of listener of button called btnSigIn. Just see the try bloc, I'm trying to start other activity called MapaActivity. Also this intent is inside addValueEventListener (a firebase listener when a field change).
In my MapaActivity Class I have basically this
class MyLocationListener implements LocationListener {
MyLocationListener(){
ubicacion = new Location("Inicio");
ubicacion.setLatitude(0.0);
ubicacion.setLongitude(0.0);
}
@Override
public void onLocationChanged(Location location) {
if (muestreando){
ubicacion = location;
txtLat.setText("Latitud: "+ location.getLatitude());
txtLon.setText("Longitud: "+ location.getLongitude());
myRef.child("lineas").child("1").child("ABC-123").child("latitud").setValue(location.getLatitude());
myRef.child("lineas").child("1").child("ABC-123").child("longitd").setValue(location.getLongitude());
setResult(1);
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
As you can see is a listener that modify some parameters from the user location in Firebase.
THE PROBLEM
The first class works perfectly and sends me to the second activity (MapaActivity).
But, when the second activity modifies the firebase database for any reason (tha i can't undestand), the first activity also listen the change n firebase and it creates again de second activity and how that. It happens as many times as the location change (it refresh the firebase and the first activity listen and trhougt again the seond activity).
Anybody knows Why ? And how can i solve. Thank You.
Upvotes: 0
Views: 3274
Reputation: 486
addListenerForSingleValueEvent
will be called again if the activity is restarting,
i.e. let's say you're launching some activity for result, when coming back to your activity, the listener will be called again.
You need to deal with your listener onActivityResult
to make sure it does not get attached to your database reference.
Upvotes: 2
Reputation: 5158
Unsubscribe events in onPause
in your Activity.
@Override
public void onPause() {
super.onPause();
myRef.removeEventListener(yourValueEventListener);
}
Same for ChildEventListener
.
Upvotes: 1
Reputation: 4074
From Google Firebase Reference
Read data once
You can use the addListenerForSingleValueEvent()
method to simplify this scenario: it triggers once and then does not trigger again.
https://firebase.google.com/docs/database/android/read-and-write#read_data_once
Upvotes: 0
Reputation: 2962
addValueEventListener
is not the event which can be triggered with click of a button or something. It will always be listening to Firebase changes and updates.
addValueEventListener
it is a callback interface which is set when there is any change in Firebase database.
Once you jump to another activity stop listening to EventListener
you have method removeEventListener which can be used to remove lsiteners to avoid getting callback from firebase.
dbref.removeEventListener(yourListener);
Upvotes: 2
Reputation: 1022
Your ValueEventListener listen to any changes that occur in the firebase. Thus, you can use ChildEventListener instead of ValueEventListener:
mDatabaseReference.child("User").addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
@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) {
}
});
With ChildEventListener, you can be more specific on when your code is supposed to read the database.
Upvotes: 0