Data is not written into the Firebase Database from Android - java

I have set up a Firebase database that has 2 nodes. One node is called "ingredients" and the other is called "orders". I set up the nodes manually by using a JSON file and I just entered 1 entry in the node "orders" manually. You can see a screenshot of the structure of the database:
Now I would like to add further entries in the table "orders" (so basically I would like to add a further row).
In my Android application I use the following code:
// in the class definition of the Fragment
public DatabaseReference firebase_DB;
...
// in the oneCreate Method of the Fragment
firebase_DB = FirebaseDatabase.getInstance().getReference("orders");
...
// when clicking on a button in the Fragment which calls the onClick method
String id = firebase_DB.push().getKey();
DB_Object_Test currentOrder= new DB_Object_Test("testInfo_2", "testName", 2);
firebase_DB.child(id).setValue(currentOrder);
So basically the code runs without an error and the firebase_DB.child(id).setValue(currentOrder); is called. However, nothing changes in the Firebase console. I can't see any new entry there. The firebase database is properly connected to the app (at least Android Studio says that) and I have not specified any rules that would prohibit writing something on the database. The same data is stored without any problems in an SQLite database.
Can any one of you think about a possible reason for this problem? Why is the new row not written into the firebase database? I'll appreciate every comment.
EDIT: Here is the adjusted code that writes to the firebase database (by using 3 different approaches) after clicking a "Order" Button in the Fragment.
public void onClick(View view) {
if(view.getId() == R.id.ordering_button) {
/* Firebase approach 1
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("");
DatabaseReference usersRef = ref.child("orders");
Map<String, DB_Object_Test> order = new HashMap<>();
order.put("order_2", new DB_Object_Test("1", "testInfo_2", "testName", "2"));
usersRef.setValue(order);
*/
/*
Firebase approach 3 (by Alex)
*/
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ordersRef = rootRef.child("orders");
Map<String, Object> order = new HashMap<>();
order.put("info", "No additional information");
order.put("name", "Another Test Order");
order.put("table", "15");
Log.e("LogTag", "Before write firebase");
ordersRef.child("order_2").setValue(order).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.e("LogTag", "During on Complete firebase");
if (task.isSuccessful()) {
Log.e("dbTAG", "Data successfully written.");
} else {
Log.e("dbTAG", task.getException().getMessage());
}
}
});
Log.e("LogTag", "Afer write firebase");
/* Firebase approach 2
DatabaseReference firebase_DB = FirebaseDatabase.getInstance().getReference("orders");
String id = firebase_DB.push().getKey();
DB_Object_Test currentOrder= new DB_Object_Test(id, "testInfo_2", "testName", "2");
firebase_DB.child(id).setValue(currentOrder);
//Option 2*
//firebase_DB.setValue(currentOrder);
Log.e("LogTag", "firebase_DB.child(id): " + firebase_DB.child(id));
*/
Navigation.findNavController(getView()).navigate(...);
}
}

To be able to add another object under your "orders" node, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ordersRef = rootRef.child("orders");
Map<String, Object> order = new HashMap<>();
order.put("info", "No additional information");
order.put("name", "Another Test Order");
order.put("table", "15");
ordersRef.child("order_2").setValue(order).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("TAG", "Data successfully written.");
} else {
Log.d("TAG", task.getException().getMessage());
}
}
});
This code will work only if you set the proper security rules in your Firebase console:
{
"rules": {
".read": true,
".write": true
}
}
Remember to keep these rules only for testing purposes. Besides that, you can also attach a complete listener to see if something goes wrong.
If you want to use DatabaseReference#push() method, then you should use the following line of code:
ordersRef.push().setValue(order);
Edit:
According to your last comment:
Database location: Belgium (europe-west1)
You should check my answer from the following post and add the correct URL to the getInstance() method:
getInstance() doesn't work with other location than us-central1 in Realtime Database
In your particular case it should be:
DatabaseReference rootRef = FirebaseDatabase.getInstance("https://drink-server-db-default-rtdb.europe-west1.firebasedatabase.app").getReference();

Related

Why my Firebase firestore data is not showing in android

I am working on an application where anyone can list their products. I am storing data in Firebase Firestore in nested collection Now I want to retrieve that data and show that on my home screen. Now the data is showing but the problem is that it is showing only when I am login in with that same number through that I list that data into Firebase but when I try to log in with another number the data doesn't show. I want that to show to everyone who logged in to the app. Basically My app is just like OLX where anyone can list anything which shows to everyone.
MY CODE TO RETRIEVE THE DATA
//CODE TO GET CURRENT ID OR USER
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
//CODE TO GET THE DATA FROM FIREBASE
DocumentReference uidRef = firebaseFirestore.collection("listing_details").document(uid);
CollectionReference roomDetailsRef = uidRef.collection("room_details");
String doc_id = roomDetailsRef.document().getId();
roomDetailsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
if (document != null) {
RoomsDetails obj = document.toObject(RoomsDetails.class);
roomsDetails.add(obj);
}
}
roomsAdapter.notifyDataSetChanged();
} else {
Log.d(TAG, task.getException().getMessage()); //Never ignore potential errors!
}
}
});
You have .document(uid) in your path where UID is User ID of user currently logged in. When you use another phone number, that's a different user.
If you want to fetch room_details documents from all listing_details documents then you can use Collection Group queries like this:
db.collectionGroup("room_details").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
// ... iterate over all docs and render
}
});

Tried to add a new field of data to Firebase user when registering, but no update X method in FirebaseUser.class file

I am using the Realtime database, so the users are store in the database. I am attempting to implement a 'currentLocation' field for the FirebaseUser objects so that I can eventually create a list for each user of nearby users. I was already using a HashMap to input the data, so I just added hashmap.put('currentLocation', ''); to create an empty current location field that can be updated later.
Unfortunately though I cannot find a way to set/update the currentLocation field as there is no updateCurrentLocation() method in the FirebaseUser.class. How do I add this method to this read-only file? Is this even the best way to do this?
Code:
//Dashboard.java
usedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
//get current user
final FirebaseUser fUser = FirebaseAuth.getInstance().getCurrentUser();
//Updates the firebase db user with their current location.
fUser.updateCurrentLocation(location);
//This method is not in the firebaseuser.class file but needs to be!
//fUser.updateCurrentLocation(location);
}
}
});
//RegisterActivity.java
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, dismiss dialog and start register activity
progressDialog.dismiss();
FirebaseUser user = mAuth.getCurrentUser();
//Get user email and uid from auth
String email = user.getEmail();
String uid = user.getUid();
//When user is registered store user info in firebase realtime database too
//using HashMap
HashMap<Object, String> hashMap = new HashMap<>();
//put info in hasmap
hashMap.put("email", email);
hashMap.put("uid", uid);
hashMap.put("name", ""); //will add later (e.g. edit profile)
hashMap.put("currentLocation", "");
hashMap.put("onlineStatus", "online"); //will add later (e.g. edit profile)
hashMap.put("typingTo", "noOne"); //will add later (e.g. edit profile)
hashMap.put("phone", ""); //will add later (e.g. edit profile)
hashMap.put("image", ""); //will add later (e.g. edit profile)
hashMap.put("cover", ""); //will add later (e.g. edit profile)
//firebase database instance
FirebaseDatabase database = FirebaseDatabase.getInstance();
//path to store user data named "Users"
DatabaseReference reference = database.getReference("Users");
//put data within hashmap in database
reference.child(uid).setValue(hashMap);
Toast.makeText(RegisterActivity.this, "Registered...\n"+user.getEmail(), Toast.LENGTH_SHORT).show();
startActivity(new Intent(RegisterActivity.this, DashboardActivity.class));
finish();
//FirebaseUser.class Bytecode
#NonNull
public Task<Void> updateEmail(#NonNull String email) {
Preconditions.checkNotEmpty(email);
return FirebaseAuth.getInstance(this.zza()).zzn(this, email);
}
#NonNull
public Task<Void> updatePassword(#NonNull String password) {
Preconditions.checkNotEmpty(password);
return FirebaseAuth.getInstance(this.zza()).zzo(this, password);
}
#NonNull
public Task<Void> updatePhoneNumber(#NonNull PhoneAuthCredential credential) {
return FirebaseAuth.getInstance(this.zza()).zzp(this, credential);
}
#NonNull
public Task<Void> updateProfile(#NonNull UserProfileChangeRequest request) {
Preconditions.checkNotNull(request);
return FirebaseAuth.getInstance(this.zza()).zzq(this, request);
}
FirebaseUser class, has only a few fields that are related to the authentication. If you need more details about your users, you should create a POJO class to store additional data.
This data can be stored either in Cloud Firestore or in the Realtime Database so it can be later used.
Please also note, the Realtime Database doesn't store null values. Firestore does.
To update the location of the current user, you can do:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference reference = database.getReference("Users");
reference.child(uid).child("currentLocation").setValue("the location");
Since you mention wanting to find nearby users, I recommend checking out: Query for nearby locations and https://github.com/firebase/geofire-android/

How to check if a certain value is there in a Firebase database

What I want is: to check if the user input value is available in the database. I have an EditText in my app, the user enters a phone number. When he clicks the button, the button requests to see in the database to see if the user input matches any record of a phone number in the database.
I haven't done anything um lost, but I have a screenshot of my database structure.
To check for example, if "+263782876566" already exists in the database, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference officeRef = rootRef.child("Users").child("Office");
Query queryByPhone = officeRef.orderByChild("phone").equalTo("+263782876566");
officeRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
String type = ds.child("type").getValue(String.class);
Log.d(TAG, type);
}
} else {
Log.d(TAG, task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
So we are using a reference that points to Users -> Office and then we create a Query object to actually check within all children if the "phone" property holds a specific value. If we find some results, we simply log the type. In your particular example, the result in the logcat will be:
Office member

Firebase data update

I want to change the user role.
I have a collection of users with the user id. Each user has fields with mail, name, role, etc.
DatabaseReference reference;
reference = FirebaseDatabase.getInstance().getReference("users");
reference.child(document.getId()).child("Role").setValue("3");
document.getId() shows the correct user id but nothing changes in the database
Database screen
Ok it was stupid mistake. I'm working on Cloud Firestore and I've tried to change to
Realtime Database
Correct
DocumentReference docfer=db.collection("users").document(document.getId());
Map<String,Object> map = new HashMap<>();
map.put("Role","3");
docfer.update(map)
Your screenshot displays a Firestore database and not a Firebase Realtime Database. Both are apart of Firebase services but are actually two totally different products. So you need to use method that are apart of Firestore SDK. To change the value of the "Role" property, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference usersRef = rootRef.collection("users");
DocumentReference uidRef = usersRef.document(uid);
uidRef.update("Role", "3").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("TAG", "The document is updated successfully!");
}
}
});
The result will be the update of the "Role" property from "0" to "3".
Use "update" :
reference.child(document.getId()).child("Role").update("3");
than "setValue":
reference.child(document.getId()).child("Role").setValue("3");

How Should I fetch the document fields and use them in another map for another collection?

How should I fetch the document fields from one collection and combine them to add a new document to another collection? I have attached picture of the database how does it looks, I want to fetch the fields from the collection show and want to update it to the new collection along with some other data:
private void savePost(String mPostTitle, String mPostContent, String mlistSpinnerC) {
final DocumentReference docRef = FirebaseFirestore.getInstance().collection("users").document(mauth.getCurrentUser().getUid());
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document != null) {
String username = (String)
document.get("username");
String email= (String) document.get(email);
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
postMap.put(Constants.POSTTTITLE, mPostTitle);
postMap.put(Constants.POSTCATEGORY, mlistSpinnerC);
postMap.put(Constants.POSTCONTENT, mPostContent);
postMap.put(Constants.TIMESTAMP, (System.currentTimeMillis()/1000));
postMap.put(Constants.USER_ID,mauth.getCurrentUser().getUid());
postMap.put("username", username);
PostsRef.document().set(postMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Intent toHomeActivity = new Intent(AddPostActivity.this, MainActivity.class);
startActivity(toHomeActivity);
}
}
});
I am just not able to map the fields from one collection to another collection, please guide me the correct method to that.
By the time you are trying to add the username to your postMap using the following line of code:
postMap.put("username", username);
The data has not finished loading yet from the database and this is because the listener you have added to your get() call is being invoked some unknown amount of time later after your query finishes. You don't know how long it's going to take, it may take from a few hundred milliseconds to a few seconds before that data is available. The onComplete() method has an asynchronous behavior, that's why you cannot get that username in such a way.
A quick solve for this problem would be to move all that block of code related to adding data to the postMap, inside the onComplete() method. In this you are waiting for the callback and username your will be available. Otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Categories

Resources