I am trying to add a timestamp field in an Android client with Firebase Firestore.
According to the documentation:
Annotation used to mark a Date field to be populated with a server
timestamp. If a POJO being written contains null for a
#ServerTimestamp-annotated field, it will be replaced with a
server-generated timestamp.
But when I try it:
#ServerTimestamp
Date serverTime = null; // I tried both java.util.Date and java.sql.Date
//...
Map<String, Object> msg = new HashMap<>();
// ... more data
msg.put("timestamp", serverTime);
On the Cloud Firestore database this field is always null.
That is not the correct way of how to add the time and date to a Cloud Firestore database. The best practice is to have a model class in which you can add a date field of type Date together with an annotation. This is how your model class should look like:
import java.util.Date;
public class YourModelClass {
#ServerTimestamp
private Date date;
YourModelClass() {}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
When you create on object of YourModelClass class, there is no need to set the date. Firebase servers will read your date field, as it is a ServerTimestamp (see the annotation), and it will populate that field with the server timestamp accordingly.
Another approach would be to use FieldValue.serverTimestamp() method like this:
Map<String, Object> map = new HashMap<>();
map.put("date", FieldValue.serverTimestamp());
docRef.update(map).addOnCompleteListener(new OnCompleteListener<Void>() {/* ... */}
use FieldValue.serverTimestamp() get server timestamp
Map<String, Object> msg = new HashMap<>();
msg.put("timestamp", FieldValue.serverTimestamp());
I have similar problem, and I found this at my catlog and solved my problem
firebaseFirestore = FirebaseFirestore.getInstance();
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setTimestampsInSnapshotsEnabled(true)
.build();
firebaseFirestore.setFirestoreSettings(settings);
I had a similar problem,
I was getting the exception ...has type java.sql.Timestamp, got java.util.Date ..., so I just replace the type from Timestamp to Date ( from java.util.Date) and worked fine.
Related
I am building a list in flutter and need to sort it by date by showing the most recent timestamp first.
The list is created from a json like the one below:
[
{
"id":100,
"timestamp":"2021-02-02T15:15:11Z",
"name":"Entry1"
},
{
"id":101,
"timestamp":"2021-03-02T11:12:56Z",
"name":"Entry2"
}
]
Once the json is fetched with the fetchEntries function, I'd like to sort the list. This is my code:
class Values extends Object {
int id;
String timestamp;
String name;
Values(
{this.id,
this.timestamp,
this.name});
Values.fromJson(Map<String, dynamic> json) {
id = json["id"];
timestamp = json["timestamp"];
name = json["name"];
}
}
List<Values> _myList = [];
fetchReport() {
_timer = new Timer.periodic(Duration(seconds: 1), (timer) {
fetchEntries(dates.id.toString(), dates.from, dates.to)
.then((value) => {
_myList.addAll(value),
_postsController.add(1),
setState(() {})
});
_timer.cancel();
});
//This is the sort code that doesn't work
_myList.sort((a,b)=> a.timestamp.compareTo(b.timestamp));
}
Alternatively, the list can be sorted by id in decreasing order but the timestamp method is preferred. Any suggestions how to do it properly?
It is better to parse time after fetch data.
_myList.sort((a,b) {
DateFormat formatter = DateFormat("yyyy-MM-ddTHH:mm:ssZ");
DateTime aTime = formatter.parse(a["timestamp"]);
DateTime bTime = formatter.parse(b["timestamp"]);
return aTime.compareTo(bTime);
//return bTime.compareTo(aTime);
}
I think that issue why sorting does not work is that _myList.sort function is called before _myList is filled with data. The reason of that is that _myList is populated in future (when callback of fetchEntires(...).then) is called, while sort function is called right after timer is created (after Timer.periodic constructor).
In order to fix that you need to move _myList.sort to callback just after list is populated with data.
Regarding sorting itself.. While it should work comparing date in the format of your example, I would rather parse time to milliseconds and then compare those instead. Reason is that once you change date format to different one, like 'dd-MM-yyyy' sorting will be broken.
May I ask if there is any implementation to collect the time when the first data is updated. For example, there is a queue function in my app. When an user has taken the queue ticket, Firebase will then be updated.
Therefore, I would like to know the time that the first user in the queue.
Is there any code for this in Android Studio? Many thanks!!
The Firebase Database does not store metadata (informations like the timestamp) for CRUD operations that are performed. Because of that, you need to store this kind of data yourself by creating your own mechanism.
In fact, you need to create a new field for each child you want to trace and change the value of the timestamp every time a action is performed. The best practice within a Firebase database is to save your data as a timestamp using: ServerValue.TIMESTAMP.
Note, that when you are saving the timestamp, you are saving as a Map and when you are retrieving, you are retrieving it as a long.
To set the timestamp, I recommend you to use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Map<String, Object> map = new HashMap<>();
map.put("timestamp", ServerValue.TIMESTAMP);
rootRef.child("yourNode").updateChildren(map);
To get you data back, I recommend you using the following method:
public static String getTimeDate(long timeStamp){
try{
DateFormat dateFormat = getDateTimeInstance();
Date netDate = (new Date(timeStamp));
return dateFormat.format(netDate);
} catch(Exception e) {
return "date";
}
}
This question already has answers here:
Firebase query by date string
(2 answers)
Closed 5 years ago.
Using Firebase, the Date is stored as : dd/MM/yyyy in the Firebase DB in String format.
I'm not getting desired results when using orderBy to order my entries by date.
dbInstance.orderByChild("eventDate").startAt(currentDate).addListenerForSingleValueEvent(eventListener);
This is what I'm using to display entries. It works fine. But the problem is with dates not being sorted correctly.
So, if today is 02/05/17 , entry with date in the above image won't display because on comparing these two strings, the one in the image is smaller.
How can this be corrected? Please help!!
The best practice is to save your data as a TIMESTAMP like this: ServerValue.TIMESTAMP and not as a String.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Map map = new HashMap();
map.put("time", ServerValue.TIMESTAMP);
ref.child("yourNode").updateChildren(map);
And to get the data back, i suggest you use this method:
public static String getTimeDate(long timeStamp){
try{
DateFormat dateFormat = getDateTimeInstance();
Date netDate = (new Date(timeStamp));
return dateFormat.format(netDate);
} catch(Exception e) {
return "date";
}
}
To solve your problem, you only need to create a query based on the correct DatabaseReference and than orderByValue("timestamp");
Hope it helps.
Hello I am creating an Android app that lists local events happening around my campus. Each "event" has children for storing the title, image, category, info, and date. I was wondering what the best way would be to delete events that are past the current date. The date is formatted mm/dd/yy. I don't have much experience with using date functions in Java, and could use some advice.
Here is an example of an event. Here is the source code for reference. Any help is greatly appreciated.
The best practice is to save your data as a TIMESTAMP like this ServerValue.TIMESTAMP.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Map<String, Object> map = new HashMap<>();
map.put("time", ServerValue.TIMESTAMP);
ref.child("yourNode").updateChildren(map);
And to get the data back, i suggest you use this method:
public static String getTimeDate(long timeStamp){
try{
DateFormat dateFormat = getDateTimeInstance();
Date netDate = (new Date(timeStamp));
return dateFormat.format(netDate);
} catch(Exception e) {
return "date";
}
}
To solve your problem, you only need get the date from your database and compare it with the current date and time. If the value of TIMESTAMP is less than the current date and time, than you can delete that particular event.
Hope it helps.
You can filter the fire base response on date itself
ex:
DatabaseReference mDatabaseReference =FirebaseDatabase.getInstance().getReference().child("table name");
ref.orderByChild("date").startAt(startDate).endAt(endDate).on("child_added", function(snapshot){
console.log("got the data!", snapshot);
});
I am working on a project which I use SQLite as database, I want to change it with firebase since operations are easier, but I looked at document but I don't know how to save time. Should I do it seperately like day, month, year or is there any way to do it? Thanks in advance.
you can store value of Firebase using Hashmap.
DatabaseReference fb = FirebaseDatabase.getInstance().getReference();
HashMap setvalues = new HashMap();
setvalues.put("last_message_time", ServerValue.TIMESTAMP);
fb.child("rootname").updateChildren(setvalues);
The best practice is to save your data as a TIMESTAMP like this ServerValue.TIMESTAMP. And to get the data back, i suggest you use this method:
public static String getTimeDate(long timeStamp){
try{
DateFormat dateFormat = getDateTimeInstance();
Date netDate = (new Date(timeStamp));
return dateFormat.format(netDate);
}
catch(Exception e){
return "date";
}
}