I'm trying since a while to add timestamp on my posts in Firebase, but I'm sadly unsuccessful. I have already tried many advises from stackoverflow, but none worked. Please help me on how to add a timestamp field under each post.
I would to know what's wrong with my code.
final DatabaseReference newPost = mDatabase.push();
mDatabaseUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Long timestamp = (Long) dataSnapshot.getValue();
System.out.println(timestamp);
newPost.child("title").setValue(title_val);
newPost.child("desc").setValue(desc_val);
newPost.child("image").setValue(downloadUrl.toString());
newPost.child("uid").setValue(mCurrentUser.getUid());
newPost.child("username").setValue(dataSnapshot.child("name").getValue()).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
startActivity(new Intent(PostActivity.this, MainActivity.class));
}
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mDatabaseUser.setValue(ServerValue.TIMESTAMP);
mProgress.dismiss();
Firebase Database structure:
{
"Blog":{
"-Ke1osQRFVs0fuqx9n18":{
"desc":"again again",
"uid":"FBwMzHJGP4U10LnLOwluy4BVyJ52",
"username":"OziBoo"
}
},
"Users":{
"vi6Qd1AafidNGGV4roBhdLPZYGN2":{
"image":"firebasestorage.googleapis.com/v0/b/agrodesk-b30ff.appspot.com/...",
"name":"Ozi"
}
}
}
There are a lot of error and misuse in your code. Please understand this first:
ref.addValueEventListener(...) is used for listening to every changes made in data referenced by ref
ref.setValue(yourValue) is used to set the value of data referenced by ref object
setValue(...).addOnCompleteListener(...) is used if you want to execute something after value has been updated
If I understand it correctly, all of your sample code you write for writing value into database, right? But you, not knowingly, used addValueEventListener() instead.
So your code to write the value into new child inside "Blog" should be like this:
// Here I use HashMap to make it more simple
// You can (and better to) use your custom object as value container
HashMap<String, Object> value = new HashMap<>();
value.put("title", "your-title");
value.put("desc", "your-desc");
value.put("timestamp", ServerValue.TIMESTAMP);
// ... etc
// the following code will create a reference object pointing at "Blog"
DatabaseReference ref = FirebaseDatabase.getInstance().getRreference("Blog");
// the following code will make a new child inside data referenced by ref (in this case, "Blog")
DatabaseReference newBlog = ref.push();
// the following code is the code that actually update the data of referenced point
newBlog.setValue(value)
// addOnCompleteListener is optional
.addOnCompleteListener(new ... {
// code placed here will be executed when your data is updated
...
});
Hope this helps.
Note:
There I just show you what you want to achieve for this case and this case only. Please read more documentation, guide, and tutorial about Firebase Database. It might take long, but once you understand it, it's actually quite simple.
Related
I am using addOnCompleteListener, but I need to setValue to more than one child at time, it will not be good if I check if 1st child updated then update the 2nd then the 3rd ... etc, it will be very complicated
Also I need to test addOnFailureListener, addOnCanceledListener ,and when they will be triggered and what the best action should be taken in these case
From the docs:
public Task<Void> setValue (Object value)
Set the data at this location to the given value. Passing null to setValue() will delete the data at the specified location. The native types accepted by this method for the value correspond to the JSON types:
Boolean
Long
Double
String
Map
List
Therefore if you have multiple setValue(), you can do the following:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
Map<String, Object> values = new HashMap<>();
values.put("name","peter");
values.put("age","100");
ref.setValue(values).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
System.out.println("completed");
}
});
Of you can use a pojo class instead of map.
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DatabaseReference#setValue(java.lang.Object)
I'm trying to update a specific field in a document using POJO, as written in the doc. I could use SetOptions.mergeFields(). But it's updating other fields with null instead of keeping the other fields (which excluded from mergeFields) untouched. Is it intended?
Here is my code :
UserModel userModel = new UserModel();
userModel.setStatus(0);
setTask = documentReferenceToUse.set(userModel, SetOptions.mergeFields("status"));
setTask.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
if (!emitter.isDisposed())
{
emitter.onComplete();
}
}
}).addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
if (!emitter.isDisposed())
{
emitter.onError(e);
}
}
});
And here is my document structure :
[Solved]
Turned out the issue came from my Firebase wrapper code. So there is no actual problem on the Firebase SDL side.
Edit: After taking another closer look at your code, I found that you need to change this line of code:
setTask = documentReferenceToUse.set(model, SetOptions.mergeFields("status"));
with:
setTask = documentReferenceToUse.set(userModel, SetOptions.mergeFields("status"));
You are passing as the first argument, not the object that you have just created but another one. So, the correct object that must be used is: userModel.
You can also use another approach, by getting that entire object from the database. Having the object, you can use setters to change the value of the fileds beneath it. After you have used the setters, you can use set() method directly on the reference to add the object the database.
documentReferenceToUse.set(userModelFromDatabase);
You can also use a Map in order to make an update:
Map<String, Object> map = new HashMap<>();
map.put("status", 0);
documentReferenceToUse.update(map);
DatabaseReference databaseReference=mDatabase;
String queryText="Hotel";
databaseReference.orderByChild("Coupon")
.startAt(queryText)
.endAt(queryText+"\uf8ff");
Here I attached the code which I used to get child names of "Coupon" when I entered the "Hotel" query under the Coupon.But I got blank.I supposed to get Hotel1,Hotel2 object.I'm new to firebase.So hope your support .Thanks in advance.
In the Web version, they use something called ElasticSearch, you could try to read more here: https://firebase.googleblog.com/2014/01/queries-part-2-advanced-searches-with.html
But for Android, I think there isn't any functionality to perform a search like that. What I would do is to query all the records then filter them myself:
DatabaseReference databaseReference = mDatabase;
mDatabase.addValueEventListener(new ValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot val : dataSnapshot.getChildren()){
//I am not sure what record are you specifically looking for
//This is if you are getting the Key which is the record ID for your Coupon Object
if(val.getKey().contains("Hotel")){
//Do what you want with the record
}
//This is if your are querying for the hotel child
if(val.child("hotel").getValue(String.class).contains("Hotel")){
//Do what you want with the record
}
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
}
Don't load your whole database to filter out needed data. It produces unnecessary traffic which has to be loaded, calculated and deleted. Instead, use:
DatabaseReference myRef = FirebaseDatabase.getDatabaseReference();
Query searchQuery = myRef.child("Coupon").orderByChild("hotel").equalTo("yourSearchString");
To make this code work, you also have to add indexOn on your corresponding attribute in the rules (of Firebase Database console).
I have the following data structure on firebase for the user MF0qeRA4p7djfjgXxqwFOck3m6p02. I want to get the value of item3 to populate a single field into the User interface on an Android App. I have been looking through samples on Stackoverflow, but all I have found are outdated and do not work with the current version of firebase. I'm new to firebase completely and this is my first app on android. I've got the oncreate user method to populate the users email address and add the 4 item fields, but retrieving the data I'm completely lost and I am not sure where to even begin.
-Users
---MF0qeRA4p7djfjgXxqwFOck3m6p02
------item1:"1"
------item2:"2"
------item3:"3"
------item4:"4"
According to what I can identify is, you are facing problem retrieving data from this reference. Here is the code:
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users");
databaseReference.child("MF0qeRA4p7djfjgXxqwFOck3m6p02").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> map=(Map<String, Object>)dataSnapshot.getValue();
String item3=(String)map.get("item3");
display(item3);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Hope this helps.
You can create a custom model and inside you can insert elements. Something like this:
public class Item {
private List<Object> ojects;
}
There you can save instance of Item on database. In this case you have more controll. Other case is to use push() method, that will generate a new encoded key, something like this:
mDatabase.child("items").push().put(new Object());
I'm trying to add a new child using the DatabaseReference in my Firebase Android app. I'm doing:
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference()
mDatabase.child("childToAdd").setValue(1);
I can do this with a regular Firebase Reference as it would add the child to the database if it isn't there.
How could I go about doing this with DatabaseReference?
Edit: Thanks for all the suggestions but I'm having issues with the following code. When it enters the if block it does not push the data onto the database.
https://gist.github.com/rounaksalim95/a5cba332400c6caf8320f15b0cbf06e8
When I try this with the old Firebase reference I get error code 11 (User code called from firebase runloop) and with the new database reference I get error code -3 (PermissionDenied even though I have no security rules).
Update:
I got it to do what I wanted to using a single value event listener:
Firebase userRef = new Firebase(BASEURL + "userData");
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(user.getUid()).getValue() == null) {
userRef.child(user.getUid()).setValue(1);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
However database reference doesn't let me add values like this.
You'll need to call push() to generate a unique key for the new data:
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference()
mDatabase.push().setValue(1);
This will append the new value at the end of the list.
By combining the push() and child() methods, you can create multiple lists of children in the database:
mDatabase.child("numbers").push().setValue(1);
mDatabase.child("numbers").push().setValue(53);
mDatabase.child("numbers").push().setValue(42);
mDatabase.child("letters").push().setValue("a");
mDatabase.child("letters").push().setValue("z");
mDatabase.child("letters").push().setValue("c");
See the section append to a list of data in the Firebase documentation.
Another post mentioned to check your gradle app file to ensure you have the latest version of the Firebase as follows:
compile 'com.google.firebase:firebase-core:10.0.1'
compile 'com.google.firebase:firebase-database:10.0.1'
I think this should fix many issues that could arise from using older versions.
I hope this helps.
You cannot add anything to the database if you're not authorized. You can do one of the following:
Either set this to your rules tab in firebase console:
{
"rules": {
".read": true,
".write": true
}
}
Or you must create an authentication first (try with email/pass) and create user with
createUserWithEmailAndPassword(email, password)
and then sign in with:
signInWithEmailAndPassword(email, password)
and you need to enable sign-in with email/pass in your console as well.
And then you can write data to your database.
Use push() before set value in the firebase. It will create new user every time when you send value in the database.
Check this sample, it may help you out.
public class FirebaseUserDetails
{
private String mDisplayName;
public String getmDisplayName() {
return mDisplayName;
}
public void setmDisplayName(String mDisplayName) {
this.mDisplayName = mDisplayName;
}
}
Add your value to firebase database,
FirebaseUserDetails firebaseUserDetails = new FirebaseUserDetails();
firebaseUserDetails.setmDisplayName("arunwin");
DatabaseReference pathReference = FirebaseDatabase.getInstance().getReference().child("contacts");
pathReference.child("arun").setValue(firebaseUserDetails).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
}
});
And your result value will be added in your database like the below,
contacts:
arun:
mDisplayName:"arunwin"
In my case i am adding new child like this!
NOTE : Here i am adding new child refresh_token to my firebase database
FirebaseDatabase.getInstance().getReference().child("RegistrationModel").child(userId)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, String> stringStringHashMap =(Map<String, String>) dataSnapshot.getValue();
stringStringHashMap.put("refresh_token",refreshedToken);
FirebaseDatabase.getInstance().getReference().child("RegistrationModel").child(userId)
.setValue(stringStringHashMap);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});