I have a ValueEventListener, and the inner code is never being reached. My app is authenticating, but I can't retrieve data and I'm not sure what I'm missing. In the code below, when I check, uid has the correct value, and the data path ("Users/[uid]") is correct, but none of the inner code in the value event listener is never being reached. I've also tried to place a listener right at the root, with the same result.
I've set up Firebase using the menu options, adding both Authentication and Realtime Database to my app; authentication is working fine, so I'm wondering if there is something else that needs to be configured for the realtime database? I've read the documentation and walked through many examples but I can't see anything I'm missing.
uid = FirebaseAuth.getInstance().getCurrentUser().getUid().toString();
DatabaseReference userRef = ref.child("Users").child(uid).getRef();
ValueEventListener userListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user == null) {
SettingsLoad();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("User", "User not found" );
}
};
userRef.addListenerForSingleValueEvent(userListener);
Try this!
I've just added else condition and log or toast the results!!
uid = FirebaseAuth.getInstance().getCurrentUser().getUid().toString();
DatabaseReference userRef = ref.child("Users").child(uid).getRef();
ValueEventListener userListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user == null) {
SettingsLoad();
}
**else {
Log.d("tag","User Found!");
}**
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("User", "User not found" );
}
};
userRef.addListenerForSingleValueEvent(userListener);
Related
In my android application, when the user logs in, I need to check my realtime database to determine if the users ID exists within this database. Once the users ID has been located, i then need to retrieve the parent node of this ID in order to determine if the user logging in is a customer or employee. I'm having some difficulties coding this, as i'm relatively new to using firebase.
Here is my code so far:
final String user_id = Objects.requireNonNull(firebaseAuth.getCurrentUser()).getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
ValueEventListener eventListener = new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for(DataSnapshot ds : dataSnapshot.getChildren())
{
if(ds.child(user_id).exists())
{
//check if employee or customer?
String cust_or_emp = ds.child(user_id).getKey();
Log.d("test1",String.valueOf(ds.child(user_id).getKey()));
if (cust_or_emp.equals("Customers"))
{
name= Objects.requireNonNull(ds.child(user_id).child("User_Information").child("firstName").getValue()).toString();
Log.e("first name is ", "firstname :" + name);
toNextActivity = new Intent(getActivity(), MainActivity.class);
toNextActivity.putExtra("name",name);
Log.e("2first name is ", "firstname :" + name);
progressBarLayout2.setVisibility(View.GONE);
Objects.requireNonNull(getActivity()).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Objects.requireNonNull(getActivity()).startActivity(toNextActivity);
getActivity().finish();
} else if (cust_or_emp.equals("Employee")) {
//code for if the key is employee
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError)
{
Log.d("error", databaseError.getMessage()); //Don't ignore errors!
}
};
rootRef.addListenerForSingleValueEvent(eventListener);
Currently when I run my application, nothing appears to happen.
You're attaching a value listener to the root of your database. Then in your onDataChange you loop over the child node, which means that your ds snapshot is for the Users node, while you seem to think it's for the Employee and Customers node.
The fix should be to listen to the Users node instead:
rootRef.child("Users").addListenerForSingleValueEvent(eventListener);
Your current approach is highly inefficient, as (even when you fix the above) you're loading the entire Users node to check if a specific user exists in there. As you add more users to the app, this means you're loading more and more data, without using it.
A better approach is to check whether the specific user exists under each specific node:
rootRef.child("Users/Employee").child(user_id).addListenerForSingleValueEvent(new new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
... handle the Employee
}
else {
rootRef.child("Users/Customer").child(user_id).addListenerForSingleValueEvent(new new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
... handle the Customer
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
I successfully get the username by searching the subject which is saved under username in the tlocation. But what if the subject totally not exist under all username so how I am gonna detect whether the subject exist in the tlocation? If you got any idea please share it to me thank you.
here's my code
tref.orderByChild("subject").equalTo(ssubject).
addValueEventListener(new ValueEventListener() {
//ssubject is user selected subject
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (final DataSnapshot u: dataSnapshot.getChildren()) {
if(u.child("subject").getValue().equals(ssubject)){
// do some code here
}else{
searchuserlist.setEmptyView(findViewById(R.id.stv));
}
here's my database structure
This is how you can verify if the subject exists:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userRef = rootRef.child("tlocation").child("rexyou0831");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.child("subject").exists()) {
//do something
} else {
//do something else
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userRef.addListenerForSingleValueEvent(eventListener);
I have used rexyou0831 as an example. Instead of rexyou0831 you can use the userName variable.
Users is my root node, in that I have various childs created by getting the uid of the user who authenticated. Within these childs (uid) their are various childs like Info, General maintenance, Complaints.
I want to show some of the details like gCity, gProductModel from General maintenance child from all the users (uids). Each uid will have a different values of gCity, etc. Under General Maintenance, I want to retrieve all that data by setting it on an adapter and listview.
I am not able to retrieve it.
Database image
retreive code
When i am trying to retrieve data from the current user by using 'getuid()'(As shown below) ,its working fine . But when i try to retrieve all users data using' getkey()' , it isn't working .
user = FirebaseAuth.getInstance().getCurrentUser();
ref= FirebaseDatabase.getInstance().getReference("Users")
.child(user.getUid())
.child("General Maintenance");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(list_users.size() > 0)
list_users.clear();
for(DataSnapshot postSnapshot:dataSnapshot.getChildren())
{
Generalperson user =
postSnapshot.getValue(Generalperson.class);
list_users.add(user);
}
if(list_users.size() != 0)
{ ListViewAdapter adapter = new
ListViewAdapter(ServicehistoryActivity.this, list_users);
list_data.setAdapter(adapter);}
else
{
list_data.setVisibility(View.INVISIBLE);
k.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Please use this code:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference().child("Users");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.getKey();
DatabaseReference userIdRef = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.child("General Maintenence").getChildren()) {
String gCity = ds.child("gCity").getValue(String.class);
String gEmail = ds.child("gEmail").getValue(String.class);
String gPhone = ds.child("gPhone").getValue(String.class);
//and so on
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userIdRef.addListenerForSingleValueEvent(valueEventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);
If you get this error, Listen at /Users failed: DatabaseError: Permission denied is because you are not authorized to the Database, check the Rules Tab in the Realtime database and make this change:
{
"rules": {
".read": true,
".write":true
}
}
Hope it helps.
So I have a root in the database like this:
users {
"user1" {
username: "username1",
email: "email#email.com"
}
"user2" {
...
}
...
}
Now, I want to register a new user, so for that I need to check if the username that the new user choose is already chosen.
For that I created a single time event and gather all usernames in a string list:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> res = new ArrayList<String>();
Iterable<DataSnapshot> users = dataSnapshot.getChildren();
for (DataSnapshot user : users) {
res.add(user.child("username").getValue(String.class));
}
// No way to return anything
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
But I have a problem, that method is asynchronous. I need to gather all usernames and know if any exists in that list synchronously.
Is there any way to achieve this?
Currently I create a Listing object and store a bunch of fields in there. Two of the fields I need to store are the current User's email and name. I am trying to get those two fields as follows
dbRef = database.getReference().child("Users").child(emailKey);
dbRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserInfo userIn = dataSnapshot.getValue(UserInfo.class);
email1 = userIn.email;
sellerName = userIn.username;
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
After this bit of code I have the line
DatabaseReference temp = dbRefL.push();
temp.setValue(l);
All of this code is called by me pressing a button. The first time I press the button, the entire Listing object is pushed to Firebase just the way I want it EXCEPT the user email and username aren't there because they're blank. The second time I press the button the Strings are there how I want.
My guess is that this is because OnDataChange only executes after I push the Listing object. Is this true? How can I get OnDataChange to execute before I push the listing object?
The listener onDataChange() callbacks are asynchronous. The reason that your email and username is blank is because onDataChange hasn't been executed yet to make sure you push data after email and username are retrieve, put the code inside onDataChange()
dbRef = database.getReference().child("Users").child(emailKey);
dbRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserInfo userIn = dataSnapshot.getValue(UserInfo.class);
email1 = userIn.email;
sellerName = userIn.username;
//set up your l value
DatabaseReference temp = dbRefL.push();
temp.setValue(l);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Once you press the button above code should be called to obtain email and username then push the data as you want.
User addValueEvenListener like :
DatabaseReference map = database.getReference("field_name");
map.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String data = (String) dataSnapshot.getValue();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
****OR using****
database.getReference("field_name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e(TAG, "Field data", dataSnapshot.getValue(String.class));
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Failed to read value
Log.e(TAG, "Failed to read user", databaseError.toException());
}
});