that's my database
{
"users" : {
"-MdgDcU3Zb-TiLlTwfwU" : {
"email" : "t1#email.com",
"fname" : "test",
"lname" : "1",
"password" : "t1",
"phoneno" : "304*******"
},
"-MdgNDN23XCTyB4DsF4W" : {
"email" : "t2#email.com",
"fname" : "test",
"lname" : "2",
"password" : "t2",
"phoneno" : "333*******"
}
}
}
that's the login activity's code
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("users");
Query checkUser = reference.orderByChild("phoneno").equalTo(userphoneno);
checkUser.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
//editTextphoneno.setError(null);
//editTextphoneno.setErrorEnabled(false);
String passwordFromDB =snapshot.child(userphoneno).child("password").getValue(String.class);
if(passwordFromDB.equals(userpassword)){
//editTextphoneno.setError(null);
//editTextphoneno.setErrorEnabled(false);
Intent i = new Intent(Login_page.this, Bottomnav.class);
startActivity(i);
finish();
}else{
editTextpassword.setError("Invalid Password");
editTextpassword.requestFocus();
}
}else{
editTextphoneno.setError("Invalid Phone Number");
editTextphoneno.requestFocus();
}
}
I want the user to login through his phone number and password but every time, after entering phone no and password I click on login, the app crashes. What I have understood is that may be the user's phone number and password is not being retrieved successfully.
When you are using the following query:
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("users");
Query checkUser = reference.orderByChild("phoneno").equalTo(userphoneno);
It means that you are searching the "users" node, for all users who have the "phoneno" equal to "userphoneno". This also means that such a query may potentially return multiple results. Even if the query returns a single result, you'll need to loop through the DataSnapshot object using getChildren() method, as in the following lines of code:
checkUser.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
String passwordFromDB = ds.child("password").getValue(String.class);
Log.d("TAG", passwordFromDB);
//Add your logic
}
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
Please see that inside onComplete, in order to get the password, there is no need for a .child(userphoneno) call, as the "password" is already a child of the DataSnapshot object.
More important, never store sensitive data as passwords in plain text. Malicious users might take advantage of that. Use Firebase Authentication for that and secure the database using Firestore Security Rules.
Related
I have this database where I store user stuff. How do i get DataSnapshot only if uname is "user 1"
Database image here
You need to query on realtime database. You can query by giving a ref: ref('uploads'), order it by the field you want: orderByChild('uname') and then put your filter: equalTo('user 1')
firebase.database()
.ref('uploads')
.orderByChild('uname')
.equalTo('user 1')
.once('value')
.then(snap => {
snap.forEach(uploadSnap => {
console.log(uploadSnap.val());
});
})
.catch(error => {
console.log(error)
});
How do I get DataSnapshot only if uname is "user 1"
To be able to get elements from a Firebase Realtime Database where the "uname" property holds the value of "user 1", you need to use a query. To be sure that the DataSnapshot object you are looking for actually returns some results, then you should call exists(), as in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uploadsRef = rootRef.child("uploads");
Query queryByUserName = uploadsRef.orderByChild("uname").equalTo("user 1");
queryByUserName.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot userSnapshot : task.getResult().getChildren()) {
if(userSnapshot.exists()) {
String uname = userSnapshot.child("uname").getValue(String.class);
Log.d("TAG", userSnapshot);
}
}
} else {
Log.d("TA"G, task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
Since "user 1" already exists in the database, the result in the logcat will be:
user 1
I want to retrieve only that post where postCategory matches the user interest.
How can I achieve this type of query. Any Help??
Below is my json file of database..
"Posts" : {
"-MAKobGjdhMfJFwZ1kol" : {
"postCategory" : "Animals",
"postDesc" : "still",
"postImage" : "Image Link",
"postPersonName" : "Name",
"postPersonUid" : "CLQA22uZpLS1ErIrnoBTrC3xqBw2",
"postTitle" : "ek"
},
"Users" : {
"CLQA22uZpLS1ErIrnoBTrC3xqBw2" : {
"email" : "email",
"interest" : {
"-MA14zFcNfs1JAjux129" : {
"name" : "Developer"
},
"-MA14zFgzhL-MOBB7D6h" : {
"name" : "Shopping"
}
},
"name" : "Name",
"uid" : "CLQA22uZpLS1ErIrnoBTrC3xqBw2"
}
In firebase database you cannot have such queries.
You should use Firestore (https://firebase.google.com/docs/firestore) for such advanced queries.
firestore/query-data
firestore
To get all posts with postCategory equal to Animals, you'd do:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts");
Query query = ref.orderBy("postCategory").equalTo("Animals");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
Log.i(TAG, postSnapshot.getKey()+": "+postSnapshot.child("postTitle").getValue(String.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
If you want to retrieve posts for multiple categories, you'll have to perform a separate query for each of those and merge the results on your client.
I'd also recommend changing how you store the categories for a user. The idiomatic way is:
"Users" : {
"CLQA22uZpLS1ErIrnoBTrC3xqBw2" : {
"email" : "email",
"interest" : {
"Developer": true,
"Shopping": true
}
},
The reasons this is more common is that it automatically ensures that each value can occur only once in the interest object, since property names are by definition unique.
I have converted to Firebase for my Android development as I want to utilise the many features of Firebase (Notifications, Messaging, Storage etc), however, I am having difficulty receiving data from Firebase and cannot find detailed information online. Yes, I have tried the documentation but it does not explain the events I am experiencing.
I want to retrieve all the data that I have an insert it into an arraylist of objects. Here is a static example:
users[i] = new User("James" + (i*2.5), "Hmack00" + (i*2), "https://firebasPic_2019.03.03.05.26.35.jpg.jpg?alt=media&token=cf", "United Kingdom");
Database:
{
"Users" : {
"4PdlTlv3qjZ3BmDvrJyUut9Fnq43" : {
"Country" : "xx",
"Fullname" : "hh",
"ProfilePicture" : "htm/o/Images%2FSearchAdapter%2F4PdlTlv3qjZ3BmDvrJyUut9Fnq43%2FProfilePicture%2FProfilePic_2019.03.06.10.47.54.jpg.jpg?alt=media&token=b647708e-c6d5-4b45-bef0-3dc40301b73a",
"Username" : "hmack001"
},
"COg4r4io9hezhFpmK3adPucUXA93" : {
"Country" : "spain",
"Fullname" : "nat",
"ProfilePicture" : "hcom/o/Images%2FSearchAdapter%2FCOg4r4io9hezhFpmK3adPucUXA93%2FProfilePicture%2FProfilePic_2019.03.06.19.14.17.jpg.jpg?alt=media&token=8620b321-5cef-42f0-a828-dbb7c37c8e7d",
"Username" : "nat"
},
"Tw1xRxViygNsLqrQiaaMAvAduIu1" : {
"Country" : "uk",
"Fullname" : "harvey\n",
"ProfilePicture" : "t.com/o/Images%2FUsers%2FTw1xRxViygNsLqrQiaaMAvAduIu1%2FProfilePicture%2FProfilePic_2019.03.03.05.26.35.jpg.jpg?alt=media&token=c290e75a-5f92-4271-bcb5-c644fe1b14ef",
"Username" : "RGB"
},
"vOxr1RoDqgWogKK1lp9pfpTHc6w2" : {
"Country" : "scotland ",
"Fullname" : "greg greg",
"ProfilePicture" : "ot.com/o/Images%2FSearchAdapter%2FvOxr1RoDqgWogKK1lp9pfpTHc6w2%2FProfilePicture%2FProfilePic_2019.03.04.12.30.22.jpg.jpg?alt=media&token=27b024cf-0691-4121-8a27-26acf101ebc2",
"Username" : "greg"
},
"xecUOPeyMcQaQrgkU9ouDgK90Ai1" : {
"Country" : "ggh",
"Fullname" : "Da apply ",
"ProfilePicture" : "2FProfilePic_2019.03.03.04.58.50.jpg.jpg?alt=media&token=f35854c2-3ff9-4d18-9f7a-10c13f066c68",
"Username" : "gg"
}
}
}
Here is my code and I will explain my errors after (I have left in 'zombie' code, to show the attempts that I have made)
//Firebase Variables
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
//Firebase Data
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
userId = mAuth.getCurrentUser().getUid();
myRef = mFirebaseDatabase.getReference().child("Users").child(userId);
//Firebase Data
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) { //Function called every time a change is made to the database
showData(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { //Function called when there is an error in the database/ with the call
Log.d("Print","Cancelled Firebase: " + databaseError.toString());
}
});
}
private void showData(DataSnapshot dataSnapshot) {
int userCount = 5;
int i = 0;
for (DataSnapshot ds : dataSnapshot.getChildren()) {
//User user = new User();
//User user = new User(); //Get Count of Firebase Users
//user = new User();
if (ds.child(userId).exists()) {
/*user.setFullname(ds.child(userId).getValue(User.class).getFullname()); //set the full name
user.setUsername(ds.child(userId).getValue(User.class).getUsername()); //set the username
user.setProfilePicture(ds.child(userId).getValue(User.class).getProfilePicture()); //set the profile picture
//Display Information
Log.d("DataSnapchat Test", "ShowData Name: " + user.getFullname());
Log.d("DataSnapchat Test", "ShowData Username: " + user.getUsername());
Log.d("DataSnapchat Test", "ShowData Picture: " + user.getProfilePicture());
ArrayList<String> userArrayList = new ArrayList<>();
userArrayList.add(user.getFullname());
userArrayList.add(user.getUsername());
userArrayList.add(user.getProfilePicture());
*/
String fullname = (String) ds.child(userId).child("Fullname").getValue();
Toast.makeText(this, "Fullname: " + fullname, Toast.LENGTH_SHORT).show();
//UserListAdapter adapter = new UserListAdapter(this, R.layout.find_profiles_search, userArrayList, mProfileSearch);
//mListView.setAdapter(adapter);
i++;
}
}
}
When I debug the code the showData function is never called and neither functions within the Value Event Listener are called, is this an Async Problem?
Currently I am trying to fetch data and insert it into a variable (Literally any data, once I have a working query I can convert it to fit by manipulating child fields etc).
Question: Does the addValueListener only work when data is changed in the database? If so then what is the alternative, if not then why are the functions not operating.
I do not recieve any errors and nothing is logged to the console.
I want to put my database into an array list, I know that I shouldnt use getChildren to do this, put I am trying to test if I can get any data before I try and get all the data.
You have some really weird loops in showData(). Since you're attaching a ValueEventListener to the node of the specific user, you can just look up the property values for that specific user:
myRef = mFirebaseDatabase.getReference().child("Users").child(userId);
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("OnDataChange", dataSnapshot.getKey());
Log.d("OnDataChange", dataSnapshot.child("Fullname").getValue(String.class));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("Print","Cancelled Firebase: " + databaseError.toString());
}
});
I am using Firebase real-time database and registered user details with Email and Password authentication.
Now, I can successfully do login and logout for registered users.
Now, I have to get details of currently logged in user.
My database structure is as below :
{
"UserInfo : " : {
"User ID : CxQNTJwnoleIk9M1iYMT9TsrJst2" : {
"-Kvb_W0YWX7M8dPF7Kn9" : {
"contact" : "8888888888",
"email" : "visu#gmail.com",
"firstname" : "Vish",
"lastname" : "Mo",
"password" : "vish",
"strUserId" : "CxQNTJwnoleIk9M1iYMT9TsrJst2"
}
},
"User ID : e1VCGeshWfOeptzzj4kP1POtmhk2" : {
"-KvbTM1Jtzn3r9V7II47" : {
"contact" : "9999999999",
"email" : "ja#gmail.com",
"firstname" : "Ja",
"lastname" : "Mo",
"password" : "ja123#",
"strUserId" : "e1VCGeshWfOeptzzj4kP1POtmhk2"
}
}
}
}
For example, If I have logged in with email: visu#gmail.com then I want to get all the details of that user.
How can I do it ??
Ya, I can get Email and Displayname as below :
FirebaseUser user = firebaseAuth.getCurrentUser();
txtUsername.setText("Welcome, " + user.getDisplayName() + "\n" + user.getEmail());
But, I want to get all the details of that user from above-specified database structure. Please, guide me. Thanks.
When you do as this:
FirebaseUser user = firebaseAuth.getCurrentUser();
txtUsername.setText("Welcome, " + user.getDisplayName() + "\n" + user.getEmail());
It's just your Authentication field, not your database.
As first, you should define these field by:
private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance().getReference();
In your db structure:
mDatabase.child("UserInfo : ").child("User ID : CxQNTJwnoleIk9M1iYMT9TsrJst2").child("-Kvb_W0YWX7M8dPF7Kn9").child("contact").getValue();
In the end, refactor your db structure by simple word. UserID, Email, Password is redundant because which can be taken by Authentication Field.
Read more: https://firebase.google.com/docs/database/android/read-and-write
try this. hope this will work
FirebaseUser user = firebaseAuth.getCurrentUser();
FirebaseDatabase.getInstance().getReference().child("UserInfo")
.child(user.getUid())
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
UserClass curUser = dataSnapshot.getValue();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
And Finally, I have done as below :
private void showData() {
progressDialog=new ProgressDialog(ProfileActivity.this);
progressDialog.setMessage("Getting data...");
progressDialog.show();
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference().child("UserInfo : ").child("User ID : " + firebaseAuth.getCurrentUser().getUid());
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
progressDialog.dismiss();
User user = dataSnapshot.getValue(User.class);
txtFname.setText(user.getFirstname());
txtLname.setText(user.getLastname());
txtEmail.setText(user.getEmail());
txtPassword.setText(user.getPassword());
txtContact.setText(user.getContact());
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
Toast.makeText(ProfileActivity.this, "Couldn't get data.", Toast.LENGTH_SHORT).show();
}
};
mDatabase.addValueEventListener(postListener);
}
Created a method, in which loaded ProgressDialog first, then took a Database refrence and initialized it up to my databse node with getting UUid from FirebaseAuth instance. Attached ValueEventListener and inside method : onDataChange, used instance of DataSnapshot to get value for my User class. and Finally displayed fetched data to my textviews.
Thanks all for your efforts. upvoted.
EDIT :
My new structure is as below :
{
"UserInfo : " : {
"User ID : I6wWODplkNXqAhSCRZsH6sjf4mM2" : {
"contact" : "9999999990",
"email" : "dhaval#gmail.com",
"firstname" : "Dhaval",
"lastname" : "Patel",
"password" : "dhaval123",
"strUserId" : "I6wWODplkNXqAhSCRZsH6sjf4mM2"
},
"User ID : Nf4kDsxAXYbclt16HahkzsYABWE3" : {
"contact" : "9999999999",
"email" : "bandish#gmail.com",
"firstname" : "Bandish",
"lastname" : "Mehta",
"password" : "bandish123",
"strUserId" : "Nf4kDsxAXYbclt16HahkzsYABWE3"
}
}
I'm making a blog posting app. I need to display the posts with the name of the author and the time.
I'm adding the post to database at posts/uid/key This key is added by Firebase on pushing the values. I cannot set this key to a fixed value as each post has different name, time, and body.
Now while retrieving the data, I want to know how to get the data at posts/uid/key/
I'm using this loop to traverse all the children of posts/ But I cannot go further into the nesting as I don't know what the keys are
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
String uid = (String) postSnapshot.child("uid").getValue();
String body = (String) postSnapshot.child("body").getValue();
}
}
I'm attaching the above listener to this reference
mPostReference = FirebaseDatabase.getInstance().getReference().child("posts");
How do I get the children of the keys without getting what the keys are?
private DatabaseReference mPostReference;
mPostReference = FirebaseDatabase.getInstance().getReference()
.child("posts");
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
String uid = (String) postSnapshot.child("uid").getValue();
String body = (String) postSnapshot.child("body").getValue();
Toast.makeText(getActivity(), body,
Toast.LENGTH_SHORT).show();
}
}
Exported JSON
{
"posts" : {
"-KTGou5X14D8pq1sxyhR" : {
"body" : "first post",
"timestamp" : 1475620339666,
"uid" : "tmFt3NbcnLVlkrWQrIx1"
},
"-KTGp3mfM4krbGoTMZ8t" : {
"body" : "second post",
"likeCount" : 0,
"uid" : "tmFt3NbiwLVlkrWQrIx1"
}
}
}