I have String values in firebase database
I would like to get this String
in onClick i make a toast for display the value but the value is toasted in the second click
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_souslistecuisine);
cuisinecomplet=(ImageView)findViewById(R.id.cuisinecomplett);
FirebaseDatabase database= FirebaseDatabase.getInstance();
DatabaseReference myRef=database.getReference("Produit");
DatabaseReference key=myRef.child("Cuisine");
DatabaseReference text=key.child("cuisine complet");
text1=text.child("text1");
text1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
txt=dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
public void complet(View view) {
Toast.makeText(souslistecuisine.this, txt, Toast.LENGTH_LONG).show();
}
I tried to put text1.addValueEventListener(new ValueEventListener()) in Onclick method but same result
Just add the Toast after you already receive the String value from Firebase, as Firebase callbacks run in background thread and take time to response.
text1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
txt=dataSnapshot.getValue(String.class);
Toast.makeText(souslistecuisine.this, txt, Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Related
I have this database
I read key "20160877" to update type this is easy because there is one key.
by this way ==>
table_user.child("20160877").child("type").setValue("2");
If I put many keys like "20160877" and have value inside it and want to update type in all type in all keys how can I did this?
I tried this way but it create new key then update type in it, I want to update the existing data and not create new data
DatabaseReference table_user;
FirebaseDatabase database;
String id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_main);
database = FirebaseDatabase.getInstance();
table_user = database.getReference("Users");
}
public void current_member(View view) {
table_user.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
id =snapshot.getKey();
table_user.child(id).child("type").setValue("1");
Toast.makeText(AdminMainActivity.this, "تم تفعيل صفحة الاعضاء الحاليون", Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
public void active_C_page(View view) {
table_user.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
id =snapshot.getKey();
table_user.child(id).child("type").setValue("2");
Toast.makeText(AdminMainActivity.this, "تم تفعيل صفحة الترشح", Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
If you want to update the status of all users, you'll need to loop over the user nodes in the snapshot in your onDataChange.
So something like:
table_user.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot userSnapshot: snapshot.getChildren()) {
id = userSnapshot.getKey();
table_user.child(id).child("type").setValue("1");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
Or you can directly get the reference from the userSnapshot
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot userSnapshot: snapshot.getChildren()) {
userSnapshot.getReference().child("type").setValue("1");
}
}
This Is My Code
#Override
protected void onStart() {
super.onStart();
control.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
s2=dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
if (s1==s2){
button.setVisibility(View.INVISIBLE);
}
}
}
when trying to control visibility from Firebase above code does not work. If I try same without use of Firebase it works.
Would appreciate any advice
Actually addValueEventListener() is an ASYNC call, so before the value of s2 gets assigned it's being compared in your if(s1==s2) statement & the value of s2 is default or null while comparison.
Instead, you can try hiding your button inside your async call itself as
#Override
protected void onStart() {
super.onStart();
control.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
s2=dataSnapshot.getValue(String.class);
if ( s1.equalsIgnoreCase(s2) )
button.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
//if (s1==s2) //Remove these lines
//button.setVisibility(View.INVISIBLE);
}
You should call this line:
if (s1==s2) button.setVisibility(View.INVISIBLE);
inside your onDataChange:
#Override
protected void onStart() {
super.onStart();
control.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
GenericTypeIndicator<String> s = new GenericTypeIndicator<String>() {};
s2=dataSnapshot.getValue(s);
if (s1==s2) //you can change this line with "if (s1.equals(s2))"
button.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
}
because addValueEventListeneris asynchronous, so onDataChange will be called after onStart is finished
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.
The code looks like this:
final DatabaseReference TuidRef = usersRef.child(td);
final DatabaseReference msgRef = TuidRef.child("rec_msg");
final DatabaseReference FuidRef = TuidRef.child("fromUID");
final DatabaseReference secretRef = TuidRef.child("rec_secret");
msgRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot1) {
ms = dataSnapshot1.getValue(String.class);
flag++;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
FuidRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot2) {
fUid = dataSnapshot2.getValue(String.class);
flag++;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
secretRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot3) {
st = dataSnapshot3.getValue(String.class);
flag++;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
String flagS = "" + flag;
Log.i("flag",flagS);
if(flag > 2)
displayMessage();
I used the flag to know how many times the ValueEventListeners are triggered, but the flag is found to be 0, in the log.
td is the uid of the person who receives the message. In the picture below it is same as the parent key of other sibling Childs.
The database looks something like this, when there are no messages:
The database looks like this, when messages are received:
Edit: How can I execute the function displayMessage(), when all three of the listeners have been triggered at once?
The value is added simultaneously to all three of them in the firebase database, though.
You'll never know how many times a ValueEventListeners is triggered in the way do, because the value of flag will always remain 0. This is happening due the asynchronous behaviour of onDataChange() method which is called even before you are trying to get the data from the database. What's really happening is that you are trying to get the data from the database and immediately try to log it while the flag variable has the initial value of 0. Then, when getting the data from the database completes, it changes flag's value, but it's never read again.
A quick solve for this problem would be add three different flags inside each callback and try to log then separately only inside the onDataChange() method like this:
msgRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot1) {
ms = dataSnapshot1.getValue(String.class);
flag1++;
Log.i("flag1", String.valueOf(flag1));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
FuidRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot2) {
fUid = dataSnapshot2.getValue(String.class);
flag2++;
Log.i("flag2", String.valueOf(flag2));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
secretRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot3) {
st = dataSnapshot3.getValue(String.class);
flag3++;
Log.i("flag3", String.valueOf(flag3));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
If you need in your code to get the value of that flag outside the onDataChange() method, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
Edit:
msgRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot1) {
ms = dataSnapshot1.getValue(String.class);
flag++;
FuidRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot2) {
fUid = dataSnapshot2.getValue(String.class);
flag++;
secretRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot3) {
st = dataSnapshot3.getValue(String.class);
flag++;
Log.i("flag", String.valueOf(flag));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
I was trying to retrieve the data from user and time. But I can't access the data, it's not really accessing the database.
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_balance);
mFirebaseDatabase=FirebaseDatabase.getInstance();
cashRef=mFirebaseDatabase.getReference().child("ASSETS").child("cash_at_bank");
TextView view=(TextView)findViewById(R.id.view);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
cashRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int time=dataSnapshot.getValue(int.class);
int values =dataSnapshot.getValue(int.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
To get the time, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference cashAtBankRef = rootRef.child("ASSETS").child("Cash at bank");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Long time = ds.child("time").child("time").getValue(Long.class);
Log.d("TAG", time + "");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
cashAtBankRef.addListenerForSingleValueEvent(eventListener);
The output will be:
150555043995
//and so on