I am making an app based on firebase Realtime database. I have set rules as given below:
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"Users": {
"$uid": {
".read": true,
// or ".read": "auth.uid != null" for only authenticated users
".write": "auth.uid == $uid"
}
}
}
}
I am trying to add data by the following code in java. But getting Error.
myfire = FirebaseDatabase.getInstance();
myRef = myfire.getReference("Users").child("Some Authentic User");
//======================
btnAdmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stName = etName.getText().toString();
stRoll = etRoll.getText().toString();
etName.setText("");
etRoll.setText("");
myRef = myfire.getReference();
myRef.child("201").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
model model =new model();
model.setFb01name(stName);
model.setFb04roll(stRoll);
myRef.child("Basic").setValue(model);
Toast.makeText(getApplicationContext (),"Sorry",Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext (),"Error",Toast.LENGTH_SHORT).show();
}
});
}
});
My model class goes like this:
public class model {
String fb01name;
String fb04roll;
public model() {
}
public model(String fb01name, String fb04roll) {
this.fb01name = fb01name;
this.fb04roll = fb04roll;
}
public String getFb01name() {
return fb01name;
}
public void setFb01name(String fb01name) {
this.fb01name = fb01name;
}
public String getFb04roll() {
return fb04roll;
}
public void setFb04roll(String fb04roll) {
this.fb04roll = fb04roll;
}
}
I cannot find the error. The logcat is blank.
I was successful in adding data previously .But after changing the rules it failed.I want the database path like this:
(Main Node)Users--
(first Child)---Authenitic User(As added by "Add User")
(second child)-----some id( like '201')
(Targeted Children) 1 ------fb01name (and its value)
2------fb04roll (and its value)
Can anybody will please guide me practically?
Since onCancelled is called on your listener, that means that you don't have permission to read the data that you're trying to access. If you log the databaseError.toException() that you get in onCancelled you should also see that, as it should tell you that permission was denied.
Distilling your code down, you're attaching a listener to:
myRef = myfire.getReference();
myRef.child("201").addValueEventListener(...
So that is the path /201 in the database, where indeed your rules don't grant anyone read access.
My best guess is that the myRef = myfire.getReference(); line is a mistake, and removing it will lead to reading /Users/Some Authentic User/201, which is probably what you want to do.
Related
How do you Retrieve this from firebase?
Im trying create an app tracking the movement of the user but I cant get the location from the firebase. Ive Tried this code but the message below appears.
private void getEndLocation(){
databaseReference = FirebaseDatabase.getInstance().getReference().child("User's Location");
geoFire = new GeoFire(databaseReference);
geoQuery = geoFire.queryAtLocation(new GeoLocation(adminCurrentLatitude,adminCurrentLongitude),10);
geoQuery .removeAllListeners();
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(String key, GeoLocation location) {
if(!userFound && requestType){
userFound = true;
userID = key;
Log.d("Location", "onKeyEntered: "+userID);
}
}
#Override
public void onKeyExited(String key) {
}
#Override
public void onKeyMoved(String key, GeoLocation location) {
}
#Override
public void onGeoQueryReady() {
}
#Override
public void onGeoQueryError(DatabaseError error) {
}
});
}
Here is the message that I received:
Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding '".indexOn": "g"' at User's Location to your security and Firebase Database rules for better performance
For the query in your code you need to define an index in the security rules of your database like this:
{
"rules": {
...
"User's Location": {
".indexOn": "g"
}
}
}
Also see the Firebase documentation on indexing data and previous questions with the same error message.
I'm developing an app with Android Studio using Firebase. I want to delete a certain date but when I click on the delete button it does nothing. I can't reach to parent because it's a generated key. Any help would be appreciated.
private void deleteDate(){
String dateValue = showDate.getText().toString();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String userid = user.getUid();
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference().child("Users").child(userid).child("smokeFreeDays");
usersRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot) {
for (DataSnapshot userDataSnapshot : snapshot.getChildren()) {
String date = userDataSnapshot.getValue(String.class);
if (date.equals(dateValue)) {
snapshot.getRef().child(dateValue).removeValue();
} else if (!date.equals(dateValue)) {
snapshot.getRef().child(dateValue).removeValue();
}
}
}
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error) {
Log.w("tag", "loadPost:onCancelled", error.toException());
}
});
}
My Database:
See my comment above for debugging the issue.
But as an overall hint, I'd recommend reconsidering the data structure under smokeFreeDays to look like this:
"smokeFreeDays": {
"2021-05-09": true,
"2021-05-10": true
}
The two changes in this structure:
The date format is now ordered year-month-day, which is better suited for querying. For example, you can get all smoke free days in 2021 with: usersRef.orderByKey().startAt("2021-").endAt("2021~").
We now use the date as the key, which means we no longer have to load all smokeFreeDays to find the value to delete. You can now delete the node once you know the date with: usersRef.child("2021-05-09").removeValue().
I've tried so many ways to check if a user id is already in the firebase but all method are in vain.
Below is my code to check if user id exists but whatever data I enter it does not show the required error.
userid = findViewById(R.id.userid);
String userVal = userid.getEditText(). getText().toString();
boolean userquery = FirebaseDatabase.getInstance().getReference().child("user").orderByChild("userid").equals(userVal);
if(userquery) {
userid.setError("This user name already exists");
return;
}
Whenever I try to add existing value in the input it accepts the value and overwrites in the database.
Here is the screenshot of my firebase database.
Your code so far only sets up a query. It doesn't actually execute the query, so there's no way it can detect whether the data exists. To execute a query, you have to attach a listener to it.
So in your case, that could be something like:
boolean userquery = FirebaseDatabase.getInstance().getReference().child("user").orderByChild("userid").equals(userVal);
userquery.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (!task.isSuccessful()) {
Log.e("firebase", "Error getting data", task.getException());
}
else if (task.getResult().exists()) {
userid.setError("This user name already exists");
}
}
});
On older SDK versions the equivalent would be:
boolean userquery = FirebaseDatabase.getInstance().getReference().child("user").orderByChild("userid").equals(userVal);
userquery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userid.setError("This user name already exists");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
I am making an android app through android studio in java language. I have linked it to firebase Realtime database. There are auto generated push IDs as the last child. I want to retrieve my database values back in an activity. I am facing problem in giving reference to the push IDs.
This is what I have tried.
myRef = myfire.getReference().child("Data").child(strUID).child("Traffic").child("Wedding");
final String uid =myRef.getKey();
myRef.child(uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() == null) {
Toast.makeText(getApplicationContext(),"Data Not Available",Toast.LENGTH_LONG).show();
} else {
String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();
category basic = new category(stData1,stData2,stData3,stData4);
tvBalance.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Please provide a practical example.
Edit
This is my database structure:------------
Data>>
user id>>>>
Traffic>>>>
Wedding>>>>
Auto ID>>>
>stData1
>stData2
>stData3
>stData4 //I want to get this last value//
my json file
{
"Data" : {
"UyhzVqsz1BVFKoePa2NEmlPFu382" : {
"Traffic" : {
"Wedding" : {
"-MYKeSN8GZ8WbI-8TfVB" : {
"stData1" : "15 Apr 2021,06:43:00:pm",
"stData2" : "Wedding",
"stData3" : "kkk",
"stData4" : "100"
}
}
}
}
}
}
The only ways to get a node is by either knowing its full path, or by knowing the path to the parent node, and then some unique value under the node. Neither seems to be the case for the stData4 in your JSON, so you'll have to load the entire Wedding node and then loop over the results to get the part you want.
This isn't too bad though:
myRef = myfire.getReference("Data").child(strUID).child("Traffic/Wedding");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
Toast.makeText(getApplicationContext(),"Data Not Available",Toast.LENGTH_LONG).show();
} else {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String stData1 = childSnapshot.child("stData1").getValue(String.class);
String stData2 = childSnapshot.child("stData2").getValue(String.class);
String stData3 = childSnapshot.child("stData3").getValue(String.class);
String stData4 = childSnapshot.child("stData4").getValue(String.class);
}
category basic = new category(stData1,stData2,stData3,stData4);
tvBalance.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
The code above assumes that:
strUID has the value UyhzVqsz1BVFKoePa2NEmlPFu382
I am using the following to fetch a username from Firebase. But in this case, how do I get to know, if the username exists or not.
Firebase firebaseRef = new Firebase("<Firebasae_URL>/Users");
Query query=firebaseRef.orderByChild("username").equalTo("username");
So in your case the code should be like this, to find an username exists in your database.
Firebase firebaseRef = new Firebase("<Firebasae_URL>/Users").child("username");
firebaseRef.addListenerForSingleValueEvent(new ValueEventListener) {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// User Exists
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
The solution I found to check if a query return value was
let docRef = db.collection('videos').select('id').where('id','==',quoteData.id);
docRef.get().then(function(doc){
if(doc.size > 0){
// return value
}
else{
// no return value
}
})