Why Firebase database getUid doesn't work? - java

Initially, I wrote a code to store the value in Firebase realtime database.
mDbRef = mDatabase.getReference().child("Users");
mDbRef.child("name").setValue(rname);
mDbRef.child("email").setValue(remail);
The child value was stored under its Uid in 'Users' child.
Then I changed the code to
String name = userName.getText().toString();
mDbRef = mDatabase.getReference().child("Users").child(name);
mDbRef.child("name").setValue(rname);
mDbRef.child("email").setValue(remail);
Now, the child value was stored under its name in 'Users' child.
Now I have two issues,
If I add same name with different sub child values, it was not accepted. How to rectify it?
I wrote the following code to check user before starting an activity.
public void checkUserExists () {
final String user_id = Objects.requireNonNull(uAuth.getCurrentUser()).getUid();
mDbRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild(user_id)) {
startActivity(new Intent (LoginActivity.this, HomeActivity.class));
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
The new Intent activity was working fine when the child was under Uid. When it was changed to 'name' in lieu of Uid, the intent activity doesn't start. But if I restart the app after closing it, it directly goes to Home activity. What should be done to rectify the issue?

May I suggest something like that:
String key = mDatabase.child("users").push().getKey();
// key is generated by Firebase and is unique
mDbRef = mDatabase.getReference().child("users").child(key);
mDbRef.child("name").setValue(rname);
mDbRef.child("email").setValue(remail);
And check the documentation
happy to help!

Related

How to get child of child value from firebase whose parent value is unknown in java

I want to get data from firebase without changing my database structure because I have two condition:
When admin logins then he can see all employees data for the selected year or say year-wise.
But when employees login then they should be able to see their individual data from all the years using employee code, which is a child also (blue tick in the picture).
Below is my database structure:
The child marked in red is unknown in case of employee's access and the blue tick denotes an employee who may be present in every year.
All I want is to achieve the 2nd condition. But I am unable to get the data.
Here is my code:
private void retrieveData() {
final String shift = kvName.getText().toString();
final String employeeCode = empCode.getText().toString();
dbRef.child("Apar").child(shift);
dbRef.orderByChild(employeeCode).equalTo(employeeCode).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot datas1 : dataSnapshot.getChildren()) {
for (DataSnapshot datas2 : datas1.getChildren()) {
// String aparGrading= datas2.getKey(); //unable to figure out how to get
// Toast.makeText(Apar.this, aparGrading, Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Your current data structure makes it easy to find the information for all employees for a specific year. It does however not make it easy to find the information for a specific employee across all years.
To do the latter, you have two options:
Check each year for the presence of a node for that employee ID.
Add an additional data structure that maps from each employee ID to the years for which they have data, and then load each year's data for that employee individually
For more on this, also see:
Many to Many relationship in Firebase
Firebase query if child of child contains a value
Firebase Query Double Nested
Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly, to learn why the second approach is not as slow as you may think.
After reading the various answers on this topic linked above by Mr. #Frank van Puffelen and spending some times over it, the problem is finally solved now without changing my database structure.
Below is screenshot of the result which I wanted:
Here is my modified and working code :
private void retrieveData() {
final String shift = kvName.getText().toString();
final String employeeCode = empCode.getText().toString();
final DatabaseReference aparRef = dbRef.child("Apar").child(shift);
aparRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
list = new ArrayList<>();
if (dataSnapshot.exists()) {
for (DataSnapshot dataS1 : dataSnapshot.getChildren()) {
if (dataS1.hasChild(employeeCode)) {
AparData aparData = dataS1.child(employeeCode).getValue(AparData.class);
list.add(aparData);
rvAPAR.setHasFixedSize(true);
rvAPAR.setLayoutManager(new LinearLayoutManager(Apar.this));
rvAPAR.setItemAnimator(new DefaultItemAnimator());
aparAdapter = new AparAdapter(Apar.this, list);
rvAPAR.setAdapter(aparAdapter);
} else {
Toast.makeText(Apar.this, "No Data Found!!", Toast.LENGTH_SHORT).show();
}
}
} else {
Toast.makeText(Apar.this, "Not Data Found!!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}

android firebase db , checking id duplication problem

i want to check id duplication
i want to make id duplication check code.
so i get the id which is typed from user by using sid = id.getText().toString().trim();
and then make json trees FirebaseDatabase.getInstance().getReference().child("users").child("id").setValue("add");
by using child() method ...
and put the value using setvalue() method.
because it was not possible to use ondatachange() method... (i think this method only works when there is data so i put some no useful data) i will remove the value which is in setvalue() method later (is there another method that can be used even though there is no change... i need to check the db contents)
anyway if (data.getValue()==sid) this part
i thought it can check the id ...
but it does not work
12-25 21:06:00.771 6700-6700/com.example.pc.login D/myTag: {id=add}
android log looks like this... id is the child part... and the add is the value that i put
that is the result of the getvalue() method...
summary
:
1. how can i put the id from users to the firebase db
2. how can i get the only id value except child part
when i use getvalue() method. it takes child name and the value that i put
so if the id is exist ...user made ... user should write another...
if not... the firebase db store the id user made...
thank you for reading ... help me...
idcheckbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//store the id user created
sid = id.getText().toString().trim();
FirebaseDatabase.getInstance().getReference().child("users").child("id").setValue("add");
FirebaseDatabase.getInstance().getReference().addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
if (data.getValue()==sid) {
Log.d("myTag",""+dataSnapshot.getChildren());
Toast.makeText(MainActivity.this, "aleady exists",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "you can use this id",Toast.LENGTH_SHORT).show();
FirebaseDatabase.getInstance().getReference().child("users").child("id").setValue(sid);
Log.d("myTag",""+data.getValue());
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
because it was not possible to use ondatachange() method... (i think this method only works when there is data so i put some no useful data)
No onDataChange(DataSnapshot dataSnapshot) method is triggered once when the listener is attached, whether there is data or NOT.
If the database path where the ValueEventListener is attached is empty/null/non-existent than dataSnapshot.exits() will return false.
Hence here can be your final code:
idcheckbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sid = id.getText().toString().trim();
// No need to store the id user created
// FirebaseDatabase.getInstance().getReference().child("users").child("id").setValue("add");
FirebaseDatabase.getInstance().getReference().child(sid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// sid already exists
} else {
// sid does not exists already
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
By the way your Firebase Database will look something like this:
{
"sid_1": "...",
"sid_2": "..."
}

Android studio Firebase database queries selected value

I am having trouble trying to query some information in my database, the following picture resumes what information I am trying to fetch, I am trying to get the "productId"
This is how my database looks like:
https://i.stack.imgur.com/JhJNs.png
In fact, I am trying to get this value in order to put a condition on it. I am trying to send a notification, ONLY if the productId = 02 is selected, here is my code
if (request.getFoods().isEmpty()) {
Toast.makeText(Cart.this, "Your cart is empty", Toast.LENGTH_SHORT).show();
} else{
final DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Requests");
final Query data = tokens.orderByChild("productId").equalTo("02"); // get all node with isServerToken
data.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String order_number = String.valueOf(System.currentTimeMillis());
requests.child(order_number).setValue(request);
sendNotificationOrder(order_number);
Toast.makeText(Cart.this, "Notification sent", Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Thank you for the help!
Actually your above code would not work with orderByChild() like that. If you have multiple items in your foods node with their parent nodes being 0, 1 and so on, and you want to check their productId, then only this can be done.
For this, you'd have to make the parent child foods and call orderByChild() on it, for productId. The code would look something like this:
final DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Requests").child(id).child("foods");
tokens.orderByChild("productId").equalTo("02").addSingleValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// do what you want
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Do something for errors, don't ignore
}
However, if you have database structure with different parent nodes and there is one more median node between it and the node you want to retrieve data from, then that won't work with a code like above.
Learn more about how to make a database structure suitable for orderByChild() here.

How to check if value exists in firebase with android?

So, I recently learn about firebase database, and now i'm able to insert a data. I have this script which is to store data to my firebase .
mDatabase = FirebaseDatabase.getInstance().getReference("Biodata");
String userId = mDatabase.push().getKey();
Biodata bio = new Biodata("MyUser", "MyUser#email.com");
mDatabase.child(userId).setValue(bio);
The script above is in oncreate, so when i run the activty again and again the data will insert twice or more
and here is my firebase
Biodata
-LAuyJho4kTnJt5WuCtJ
Email: "MyUser#email.com"
Fullname: "MyUser"
My bidata class
#IgnoreExtraProperties
public class Biodata {
public String Fullname;
public String Email;
public Biodata() {
}
public Biodata(String Fullname, String Email) {
this.Fullname = Fullname;
this.Email = Email;
}
}
So, how can i prevent my app to insert same data twice ?
Please try below code may help you
public void setData(){
final DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
Query queryToGetData = dbRef.child("Biodata")
.orderByChild("Email").equalTo("MyUser#email.com");
queryToGetData.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()){
String userId = dbRef.child("Biodata").push().getKey();
Biodata bio = new Biodata("MyUser", "MyUser#email.com");
dbRef.child("Biodata").child(userId).setValue(bio);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
First of all, you don't have to call it on the onCreate method. But theres another easy way for not creating duplicates. You have to create a random key for each user. Like, say emails id is unique for all users. So
mDatabase = FirebaseDatabase.getInstance().getReference("Biodata");
Biodata bio = new Biodata("MyUser", "MyUser#email.com");
mDatabase.child("MyUser#email.com").setValue(bio);
In this way, the user's details are under their own email id. It will be easier for u to get the details too. Also, this will not create duplicates, since the email id is unique. In firebase it will look like this:
Biodata
MyUser#email.com
Email: "MyUser#email.com"
Fullname: "MyUser"
So later if you want to get the users name, you just have to
DatabaseReference ref= mDatabase.child("MyUser#email.com");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Biodata bio = dataSnapshot.getValue(Biodata .class);
// and bio.getName() for getting the name
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You should not add the email as a parent node or you will get an error.
First you are adding data twice, it is because you have this under onCreate(), it should be under a button or any event that can occur.
Second, you are generating a random id using push() so every time onCreate() is invoked new data will be added since push() is used to separate records.
To prevent this problem, add the creation of a user under a button (example under a Sign up button).
If you want to keep it under onCreate() then do the following:
mDatabase = FirebaseDatabase.getInstance().getReference("User");
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String userId=user.getUid();
Biodata bio = new Biodata("MyUser", "MyUser#email.com");
mDatabase.child(userId).setValue(bio);
The above will work if you use firebase authentication and also after login of the user. The getUid() will retrieve the user id from the firebase authentication which is unique for each user. Then you will be able to add it to the database.

How to get the push() key generated my Firebase?

As you can see from the picture I have a child FreezerItems, and under that child I have two other childs which are randomKeys that Firebase has created by using push(). My question is, how do I specifically get the key L8i2M4wNUF5wOojaFE. Also how do I get that key into my RecyclerViewAdapter. I have tried this:
holder.mDeleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDatabase = FirebaseDatabase.getInstance().getReference().child("FreezerItems");
String key = mDatabase.push().getKey();
Toast.makeText(view.getContext(), key, Toast.LENGTH_SHORT).show();
}
});
But all that ever did was show a Toast with a random key, that changes each time I click on the button
What you are doing in your code, is that you are generating each time you click on the item a new id. You are not using the one that is stored in your database. In order to use the id that was already generated once, you need to store it first. So to solve this problem, I recommend you store that random generated id provided by the push() method as a property of your model class. You database structure should look like this:
Firebase-root
|
--- FreezerItems
|
--- L8i2M4wNUF5wOojaFE
|
--- date: "3/31/2018"
|
--- name: "Ice"
|
--- freezerItemId: "L8i2M4wNUF5wOojaFE"
Then to remove that particular item, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference freezerItemsRef = rootRef.child("FreezerItems");
holder.mDeleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
freezerItemsRef.child(freezerItems.getId()).removeValue();
}
});
In which freezerItems is the object of your model class and getId() is a public getter that returns that particular id.
Event objects should contain id, to populate id of the item when you read data populate, do like this..
for (DataSnapshot adSnapshot: dataSnapshot.getChildren()) {
Event eobj = adSnapshot.getValue(Event.class);
String key = dataSnapshot.getKey();
eobj.setItemKey(key);
mDataSet.add(eobj);
}
using the id of item you can delete it when button is clicked. Do something like this...
FirebaseDatabase.getInstance().getReference()
.child("FreezerItems").child(product.getId).removeValue()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//remove item from list and refresh recyclerview
mDataSet.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mDataSet.size());
} else {
Log.d("Delete Item", "couldn't be deleted");
}
}
});
For complete example, you can see http://www.zoftino.com/firebase-realtime-database-android-example
I think it still didn't explain how do we get that id that is generated randomly.
I have many more elements when I say datasnapshot.getKey() it will return the top node but I want access nodes below this top node those are random keys. And each random key have some other values.
I belive we have to do something before .push() to get that key. Later to save in model
user---
-sSHSsdlkjjfh..
-sSHSLSHBSB...
-sSHSLKJSSKJ...

Categories

Resources