FireBase Rules indexOn Issue - android

I am trying to get all emails of users using firebase Query like below
private void searchUserByEmail(final String searchText) {
DatabaseReference mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
Query query = mFirebaseDatabaseReference.child(Constants.FB_TABLE_USERS).orderByChild(Constants.FB_EMAIL).equalTo(searchText);
query.addListenerForSingleValueEvent(new ValueEventListener() {
}}
And While Searching Any email Which is not in list I am getting a warning message in my console Like
W/PersistentConnection: pc_0 - Using an unspecified index. Consider adding '".indexOn": "email"' at table_users to your security and Firebase Database rules for better performance
And My Rules in FireBase is
{
"rules": {
".read" : "auth != null",
".write" : "auth != null",
"table_users": {
".indexOn": ["email"]
}
}
}
This is my Users Table screenshot

you should remove the brackets from ".indexOn" value
"table_users": {
".indexOn": "email"
}
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String email = snapshot.child("email").getValue();
System.out.print(email);
}
}
});

Related

I want to retrieve two values from uniquely identified data in firebase

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.

Android: Firebase Realtime database abnormal data consumption (correct configuration of the rules)

When launching the following queries by my android app firebase realtime database experiencing abnormal data consumption:
The follow is the first QUERY
final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Linea/Materiale/"+ordine+prodottoPath);
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
.....
qunatitareppNew = f.parse(snapshot.child("quantitarepp").getValue().toString()).floatValue();
...
The follow is the second QUERY
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef2 = database.getReference("Tasks");
Query query2 = myRef2
.orderByChild("idmacrofase")
.equalTo(idMacro);
query2.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot2) {
for (DataSnapshot snap : dataSnapshot2.getChildren()) {
final String idtask = snap.child("idtask").getValue().toString();
.....
I config the follow rule file in firebase realtime database rules:
{
"rules":{
".read": "auth !== null",
".write": "auth !== null",
"Tasks": {
".indexOn": ["idmacrofase","idpick","idrotolo","idtask","lastupdate",".value","dataconsegna","prodotto","checkCS"]
},
"Linea":{
".indexOn":["Materiale",".value"],
"Materiale":{ ".indexOn":[".value","quantitarepp","quantita","ordine"]},
}
}
}
Here i wrote and example of my realtime databese :
.......
"Linea" : {
"Materiale" : {
"300232044211vj01592b226" : {
"ordine" : "300232044",
"quantita" : "4"
},
"300232044211vu01315b205" : {
"ordine" : "300232044",
"quantita" : "4"
},
.....
"Tasks" : {
"101698446" : {
"idmacrofase" : "1620057379ABSI402",
"idpick" : "0030308174",
"idrotolo" : "1620057379ABSI",
"idtask" : 101698446,
"lastupdate" : "1620057379758",
},
how can i change the rules to reduce data consumption?

Read only the last 50 posts in firebase (Firebase Rules)

Every time the user retrieves the Firebase Realtime Database messages, he would like only the last 50 messages from the messaging node to be retrieved (read) through the Realtime Database rules. How to do this?
Message node structure:
+ chats
+ regionChat (ex: eua)
+ idChat (ex: 534854923)
+ messages
+ idMessage1
+ idMessage2
+ idMessage3
+ idMessage4
+ idMessage5
...
I saw this in the firebase documentation, but I can't adapt my data structure:
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 50"
}
At the moment my rules are like this:
{
"rules": {
".read": true,
".write": true
}
}
you need to enhance your "query"
this should work
{
"rules": {
".read": "query.limitToFirst <= 50",
".write": true
}
}
Or, instead of using the rules, you can do it via Query.
DatabaseReference myReference = FirebaseDatabase.getInstance().getReference();
myReference = myReference().child("chats")...child("messages");
Query query = myReference.orderByID().limitToFirst(20).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
//
for (DataSnapshot issue : dataSnapshot.getChildren()) {
// do something with the data
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

when write to the database,database is still empty after registering.how to store data in my database correctly?

I'm writing to the Firebase realtime database. How to write to the database correctly?
Where is no errors found. But I changed dependencies of adding the realtime database to the app from com.google.firebase:firebase-database:16.0.1 to com.google.firebase:firebase-database:16.0.6.
This is the defined variable
private DatabaseReference mDatabase;
this is my register activity code part
private void register_user (final String displayName, String email, String password){
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser current_user = FirebaseAuth.getInstance().getCurrentUser();
String uid = current_user.getUid();
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(uid);
HashMap<String,String> userMap = new HashMap<>();
userMap.put("name",displayName);
userMap.put("status","Hey there I am using ChatApp");
userMap.put("image","default");
userMap.put("thumb_image","default");
mDatabase.setValue(userMap);
} else {
mRegProgress.hide();
Toast.makeText(RegisterActivity.this, "Couldn't Sign in.Please Check and Try Again", Toast.LENGTH_LONG).show();
}
}
});
}
data entries should store in the database
Default security rules of Firebase Realtime Database rejects read and write. So you need to check and change security rules in firebase console.
Change the security rules into
{
"rules": {
"Users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
For more security options checkout the firebase docs

Firebase orderby() with equalTo() returns zero items

I have this rule in my firebase database
"Item":{
"$userId": {
".write": "auth != null && $userId === auth.uid"
}
}
I have this data
Item
nXQw4a2jlMg34567811glaTD0bE2
-KNJLSxfR_S8AeLj0v7d
height:20
id:-KNJLSxfR_S8AeLj0v7d
When i write the below query, everything is ok.
mDataBase = FirebaseDatabase.getInstance().getReference(FirebaseConstants.ITEM);
query = mDataBase.orderByChild("userId/height").limitToLast(2);
But the below query returns zero
public void getItems(String key){
//key is -KNJLSxfR_S8AeLj0v7d
DatabaseReference reference = FirebaseDatabase.getInstance().getReference(FirebaseConstants.ITEM);
reference.orderByChild("userId/id").equalTo(key).addValueEventListener(new MyEventListener());
}
My listener
private class MyEventListener implements ValueEventListener{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Log.d("size is "+dataSnapshot.getChildrenCount()) // returns 0
for(DataSnapShot entry: dataSnapshot){
Item item = entry.getValue(Item.class);
Log.d("height is "+ item.getHeight())
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
}
Why is it returning zero and already i have data in my firebase Db?
There are a few small problems with your code:
There is no child userId, that you are trying to order/filter on: orderByChild("userId/height"). So that means the result will be empty.
You cannot loop over a snapshot (I'm surprised that even compiles). Instead you should loop over its children: for(DataSnapShot entry: dataSnapshot.getChildren()) {...
You're using a query, but your code would be more efficient and a lot more scalable if you'd simply look up the item by their key: reference.child(key).addValueEventListener(...

Categories

Resources