I'm not sure it's disconect or DatabaseErrors event. First I have a dialog show when start loading data on Firebase, and then I want to dismiss that dialog in two case :
have internet: load data success, and I dissmiss dialog in onDataChange.
no internet connection or turn off wifi quickly when app start.
In second case, I think It's will call onCancelled, and in that method, I will dismiss dialog. But in real, it's not call onCancelled.
So, how I can dissmiss dialog on second case. Here's my code
private void getCategory() {
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child(ReferenceToFirebase.CHILD_CATEGORIES)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//do something
//then dismiss dialog
mDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
mDialog.dismiss();
}
});
}
onCancelled() is called when the server rejects the listener, typically when the user doesn't have permission to access the data.
You'll probably want to prevent attaching the listener if you don't have a connection to the Firebase Database. For that you can listen to .info/connected and only attach the listener when that is true.
mDatabase = FirebaseDatabase.getInstance().getReference();
DatabaseReference connectedRef = mDatabase.child(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
mDatabase.child(ReferenceToFirebase.CHILD_CATEGORIES)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//do something
//then dismiss dialog
mDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.err.println("Listener was cancelled");
mDialog.dismiss();
}
});
} else {
System.out.println("not connected");
mDialog.dismiss();
}
}
#Override
public void onCancelled(DatabaseError error) {
System.err.println("Listener was cancelled");
}
});
Related
In my code, when user click on a button, it calls a function.In that function data has to loaded from firebase. On successful of loading, Intent will pass to another activity with some putExtra data.
SharedPreferences pref = getApplicationContext().getSharedPreferences("My_pref", MODE_PRIVATE);
choice = pref.getInt("language", 0);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(choice==1)
{
firebase("param1","param2","English");
}
if(choice==2)
{
firebase("param1","param2","hindi");
}
}
});
public void firebase(String files,String titles,String language)
{
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference(language);
DatabaseReference myRef1=myRef.child(titles);
DatabaseReference myRef2=myRef.child(files);
myRef1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
language_title = dataSnapshot.getValue(String.class);
t=1;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
myRef2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
language_file= dataSnapshot.getValue(String.class);
f=1;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
if(t==1&&f==1) {
Intent i = new Intent(getApplicationContext(), caf.class);
i.putExtra("titles", language_title);
i.putExtra("files", language_file);
startActivity(i);
}
}
But in that case intent is only passing when I click twice.In single click Intent is not passing. where is the problem?
Any code that needs data from the database, needs to be inside the onDataChange method or be called from there.
See my answer here for a longer explanation: getContactsFromFirebase() method return an empty list.
Since you have two onDataChange methods, you'll need to make sure both have been called before starting the new activity. Using some simple flag variables to track state, you can do that with:
Declare two member fields:
boolean isTloaded, isFLoaded;
And then
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference(language);
DatabaseReference myRef1=myRef.child(titles);
DatabaseReference myRef2=myRef.child(files);
isTloaded = false;
isFloaded = false;
myRef1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
language_title = dataSnapshot.getValue(String.class);
t=1;
isTloaded = true;
if (isTloaded && isFloaded) {
startCafActivity();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
myRef2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
language_file= dataSnapshot.getValue(String.class);
f=1;
isFloaded = true;
if (isTloaded && isFloaded) {
startCafActivity();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
And then finally:
private void startCafActivity() {
if(t==1&&f==1) {
Intent i = new Intent(getApplicationContext(), caf.class);
i.putExtra("titles", language_title);
i.putExtra("files", language_file);
startActivity(i);
}
}
It might be even simpler, but I had a hard time figuring out your application logic due to the variable names. Consider using more descriptive named than t, f and caf to make it easier for others (and your future self) to understand what each part of the code does in isolation.
private FirebaseAuth firebaseAuth=FirebaseAuth.getInstance();;
private FirebaseUser firebaseUser=firebaseAuth.getCurrentUser();
/******************************After declaration**************************************/
userIDDatabaseReference=FirebaseDatabase.getInstance().getReference("login");
userIDDatabaseReference.child(firebaseUser.getUid()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.w("Show out:", "In Firebase ValueEventListener");
LoginClass tempClass=dataSnapshot.getValue(LoginClass.class);
loginID=tempClass.getLoginID();
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("Database Error: "+databaseError.getDetails());
}
});
above is my coding, I wanna retrieve loginID but my event listener does not fire as the log.w did't not print any log in my logcat, I think my function does not trigger the onDataChange() because every time it will return null for the loginID. Can someone tell me what am I missing?? I referred to all documentation related, I really don't figure out what is the problem over here.
thank you~~
Use a single value event listener to get the data one time. Use this code:
userIDDatabaseReference.child(firebaseUser.getUid()).addSingleValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.w("Show out:", "In Firebase ValueEventListener");
LoginClass tempClass=dataSnapshot.getValue(LoginClass.class);
loginID=tempClass.getLoginID();
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("Database Error: "+databaseError.getDetails());
}
});
I have very simple database
TokenAdmin:
---xccsaccxvkkgmcdds :
---token: "cxcxzcfsdfdsfdsfs"
---uid: "xccsaccxvkkgmcdds"
---hjhbnghtfgdgdgdffg :
---token: "vhghtytyryyr"
---uid: "hjhbnghtfgdgdgdffg"
Now in my code I want to check and execute some code only if it find uid equal to "hjhbnghtfgdgdgdffg"
Here is my code :
mDatabase.child("TokenAdmin").orderByChild("uid").equalTo(mycurrUser.getUID()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//say here toast "A"
} else {
//toast "B"
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// ...
}
});
Now I run the code with mycurrUser.getUID() value set to "xxx" which I don't have listed in the database. I expected the code output was toast B, but instead I always get toast A, which in my understanding, it has found the value in the db. How to fix this, where did I do wrong ?
You need to use something like this:
mDatabase.child("TokenAdmin").orderByChild("uid").equalTo(mycurrUser.getUID()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
//Toast A
} else {
//Toast B
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
Hope it helps.
I'm confused why you're using a query to load the user. You seem to store the token under they UID key already, so this would work:
mDatabase.child("TokenAdmin").child(mycurrUser.getUID()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
... user exists
} else {
... user node does not exist
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
I´m using Firebase and in the login screen I have a method that it´s called when the user put the correct login credentials(that method start a Firebase thread in order to get all the info I need for the main screen), and when the main screen opened I need to wait until that method finish, I need some kind of flag or something, let me paste you my code:
Login.java:
mProgress.setMessage("Verificando Datos Usuario...");
mProgress.show();
mAuth.signInWithEmailAndPassword(usuario, pass)
.addOnCompleteListener(Login.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Toast.makeText(Login.this, "Los Datos administrados no son correctos",
Toast.LENGTH_SHORT).show();
mProgress.dismiss();
} else{
Toast.makeText(Login.this, "Bienvenido... ",
Toast.LENGTH_SHORT).show();
AdminFirebase.loadAdmin(task.getResult().getUser());
mProgress.dismiss();
Intent intento=new Intent(Login.this, Principal.class);
startActivity(intento);
}
}
});
AdminFirebase.java:
public static void loadAdmin(FirebaseUser user){
DatabaseReference userRef=adminRef.child(user.getUid());
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Administrador administrador=dataSnapshot.getValue(Administrador.class);
Sesion.admin=administrador;
Sesion.admin.loadTaxis();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
the method I need to wait to finish to run it´s on the class Taxifirebase.java:
public static void loadTaxis(List<String> chapas){
for (String chapa :chapas) {
DatabaseReference taxiref=childRef.child(chapa);
taxiref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Taxi taxi=dataSnapshot.getValue(Taxi.class);
Sesion.taxis.add(taxi);
}
}
Thanks in advance.
If the flag is for you can use Log class.
If you need for the logic of program use a boolean and change to true when you need. Later you can check the value.
I'm using following code to fetch the data from Firebase DB but as it makes network request in background thread so I want to wait till it completes the request and get a value. For example,
boolean isAvailable=false;
usernameReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
isAvailable = true;
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressBar.setVisibility(View.GONE);
}
});
if(isAvailable){
//do something here
}
else{
//do something here
}
This snippet always execute the else part so I want to wait till the variable isAvailable get the value from database then further Execution will take place.
First create an interface like this:
public interface IsAvailableCallback {
void onAvailableCallback(boolean isAvailable);
}
Suppose your above code is in this method which takes interface object to trigger callback like :
public void isAvailable(IsAvailableCallback callback) {
boolean isAvailable=false;
usernameReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
isAvailable = true;
//this will trigger true
callback.onAvailableCallback(isAvailable);
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressBar.setVisibility(View.GONE);
//this will trigger false
callback.onAvailableCallback(isAvailable);
}
});
}
Call this method like :
isAvailable(new IsAvailableCallback() {
#Override
public void onAvailableCallback(boolean isAvailable) {
//you will get callback here, Do your if condition here
}
}