I've successfully inserted data into my firebase database.(Client App).
Now all I have to do is to retrieve data back into a text view but in a different application.(Admin Application).
public void clients()
{
String name="Abch";
String gender="Abcg";
String barber="Abcf";
String concern="Abce";
String dt="Abcd";
if(!TextUtils.isEmpty(name) || !TextUtils.isEmpty(gender) || !TextUtils.isEmpty(barber) || !TextUtils.isEmpty(concern) || !TextUtils.isEmpty(dt))
{
String id=databaseReference.push().getKey();
client client=new client(id,name,gender,barber,concern,dt);
databaseReference.child(id).setValue(client);
Toast.makeText(this, "", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "Something Went Wrong Please Check Again", Toast.LENGTH_SHORT).show();
}
}
If you want to retrieve the data in another application, you have to use eventListeners, provided you have set the rules of your database right.
There are three eventListeners you can use namely, singleValueEventListener, valueEventListener and childEventListener. Since you have not posted the structure of your database, I'm assuming you know how to get the required DatabaseReference.
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Client client = ds.getValue(Client.class);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
databaseReference.addListenerForSingleValueEvent(eventListener);
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'm developing a reservation mobile app wherein when I click the checkAvailability, it will check if the data already exists in the database. My problem is that I don't know how to access since the key is randomly generated. There is a lot of similar questions to mine but no solutions has been working for me.
Firebase Database(Screenshot):
btnAvailability.setOnClickListener
btnAvailability.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Query userQuery = database.getInstance().getReference().child("Requests")
.orderByChild("order/0");
userQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String type = dataSnapshot.child("checkIn").getValue().toString();
String type2 = dataSnapshot.child("productName").getValue().toString();
if(type.equals(checkInTV.getText().toString()) && type2.equals(beach_name.getText().toString())) {
Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
}else
{
Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
From the looks of it, you're trying to check of there is a child that has order/0 with a specific checkIn and productName under Requests. In your current data structure you can do that with:
Query userQuery = database.getInstance().getReference().child("Requests")
.orderByChild("order/0");
userQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
String type = snapshot.child("checkIn").getValue().toString();
String type2 = snapshot.child("productName").getValue().toString();
if(type.equals("Saturday, April 20, 2019") && type2.equals("The Mansion")) {
Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException()
}
});
Differences from your code:
I have a loop inside onDataChange, since a query can have multiple results.
I hardcoded the date to rule out the problem being caused by the way you input the data in the text view.
I handle onCancelled, since ignoring errors is just a bad idea.
A more efficient way to accomplish the same is to have Firebase do part of the query, like this:
Query userQuery = database.getInstance().getReference().child("Requests")
.orderByChild("order/0/checkIn").equalTo("Saturday, April 20, 2019");
userQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
String type2 = snapshot.child("productName").getValue().toString();
if(type2.equals("The Mansion")) {
Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException()
}
});
In here the change is:
I moved part of the check into the query, so that Firebase can perform that filter on the server. This means it has to download less data to the client, making it both faster and cheaper.
You'll still have to filter the second value client-side, since Firebase queries can only order/filter on one property. For more on this, see Query based on multiple where clauses in Firebase.
Note that you're querying double nested data. While you can get this to work for a specific order (orders/0 in this example), if you can have multiple orders in a request, Firebase won't be able to query across all of them.
For more on this and a solution, see: Firebase Query Double Nested
I'd also recommend reading my answers about modeling categories, because I have a feeling you'll need this soon: Firebase query if child of child contains a value
While storing data you need make user email id as first parameter so that you can access data based on user.
{"reuest":{"xyz#gmail.com":{"orders":[{"checkin":"21:29"},{"checkin":"2:19"}]},"abc#gmail.com":{"orders":[{"checkin":"21:29"},{"checkin":"2:19"}]}}}
Finally found a solution on my problem.
btnAvailability.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Query userQuery = database.getInstance().getReference().child("Requests")
.orderByChild("order/0/checkIn").equalTo(checkInTV.getText().toString());
userQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
String type2 = snapshot.child("order/0/productName").getValue().toString();
if(type2.equals(beach_name.getText().toString())) {
Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
});
I need to find the existing Child inside the Random Key and I have used OrderByChild() and EqualTo() to filter the queries but it behaves soo weird that for sometimes it showing child exists for only one Child and for sometimes it doesnot work.
i need to check for the child (date_expense) of "February_2019" exist or not? i've tried this
MainActivity
databaseReference = firebaseDatabase.getReference("Expenses_Details");
expensesaddref = databaseReference.child(username).child("Expense_Month").child(monthyr);
int currentInt=Integer.parseInt(currentdate);
numberToWord((currentInt % 100));
Log.d("date_string",String.valueOf(dateString));
final String date_expense=expensesname +"" + dateString;
final ExpenseClass expenses=new ExpenseClass(expensesname,currentdate,date_expense,totalcost);
expensesaddref.orderByChild("date_expense").equalTo(date_expense).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Toast.makeText(getContext(), "Expense Already exists!!", Toast.LENGTH_SHORT).show();
}
else {
String key = expensesaddref.push().getKey();
expensesaddref.child(key).setValue(expenses);
showListAdd(expensesname);
Log.d("Adding", "Data Adding");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
}}
Note
if child exist already in db then it should display toast but expense is again adding even though the child is already db
In the Program,
monthYr is February_2019
Currentdate is date of the present day
dateString is date in words(ie one,Eleven,Twenty)
This is the Firebase structure what Iam getting .date_expense is adding even though child is exist already
i have found that the below code working as per my need
ValueEventListener valueEventListener=new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
boolean isTitleAlreadyUsed = false;
for (DataSnapshot ds: dataSnapshot.getChildren()) {
if (ds.hasChild("date_expense") && (expDate.equals(ds.child("date_expense").getValue()))) {
isTitleAlreadyUsed = true;
}
}
if(isTitleAlreadyUsed){
Toast.makeText(getContext(),"Exist",Toast.LENGTH_SHORT).show();
}else
{
String key=expensesaddref.push().getKey();
expensesaddref.child(key).setValue(expenseClass);
showListAdd(lower_exp);
Toast.makeText(getContext(),"Added",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
expensesaddref.addListenerForSingleValueEvent(valueEventListener);
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());
}
});
I have two tables: friend_lists and users
I want to retrieve data from both. After get data from friend_lists table, I use uidfriend to get data from users. I use two method:
DataSnapshot ds;
private void getPrivateMessages(){
ValueEventListener valueEventListenerPrivateMessage = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.v("data Private message", dataSnapshot.getValue().toString();//it works fine.
ds= dataSnapShot;
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
databaseReferenceFriendLists.child(currentFirebaseUser.getUid()).addValueEventListener(valueEventListenerPrivateMessage);
}
private void getFriendInfo(){
getPrivateMessage();
ValueEventListener valueEventListenerFriendInfo = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.v("data friend info", dataSnapShot.getValue().toString);
Log.v("ds Private Message", ds.getValue().toString());//error: null variable
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
databaseReferenceUsers.addListenerForSingleValueEvent(valueEventListenerFriendInfo);
}
But my app crashed and announced null variable to me. And in logcat, it shown "data friend info" first even though i run getPrivateMessage(); first(it must be "data Private message" first then "data friend info").
What 's wrong in my code? I don't know the way firebase runs.