I'm trying to add a document in Cloud Firestore, but I need the server timestamp
for adding the document. Documents are successfully added in the collection with the correct timestamp
. I'm adding the document with an alert dialog. But when I'm returning to my activity app terminates with following errors:
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException ........ E/AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Date com.google.firebase.Timestamp.toDate()' on a null object reference at com.sasam.virtuallibrary.Models.UserLight.setTimestamp(UserLight.java:103)
For showing document's I'm using following query
Query query= FirebaseFirestore.getInstance()
.collection("Users")
.document(user.getUid())
.collection("friends")
.orderBy("timestamp", Query.Direction.DESCENDING);
My class is here
public class UserLight{
protected String name;
protected String email;
protected String uid;
protected Float rating;
protected String photoUrl;
protected long timestamp;
public UserLight(){
}
//other getters and setters
@Exclude
public long getTimestampLong(){
return timestamp;
}
public FieldValue getTimestamp() {
return FieldValue.serverTimestamp();
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp.toDate().getTime();
}
}
Code that deals with the snapshot from the query
Query query= FirebaseFirestore.getInstance()
.collection("Users")
.document(user.getUid())
.collection("friends")
.orderBy("timestamp", Query.Direction.DESCENDING);
PagedList.Config config = new PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(5)
.setPageSize(10)
.build();
FirestorePagingOptions<UserLight> options = new FirestorePagingOptions.Builder<UserLight>()
.setLifecycleOwner(this)
.setQuery(query, config, UserLight.class)
.build();
mAdapter = new FirestorePagingAdapter<UserLight, ItemFriendViewHolder>(options) {
@NonNull
@Override
public ItemFriendViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ItemFriendViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_item_friend, parent, false));
}
@Override
protected void onBindViewHolder(@NonNull ItemFriendViewHolder holder, int position, @NonNull final UserLight userLight) {
holder.txtName.setText(userLight.getName());
GlideApp.with(holder.context).load(userLight.getPhotoUrl()).into(holder.avata);
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(FriendListActivity.this,FinalChatActivity.class);
intent.putExtra("Friend", (Serializable) userLight);
startActivity(intent);
}
});
}
@Override
protected void onLoadingStateChanged(@NonNull LoadingState state) {
switch (state) {
case LOADING_INITIAL:
case LOADING_MORE:
// Do your loading animation
mSwipeRefreshLayout.setRefreshing(true);
break;
case LOADED:
// Stop Animation
mSwipeRefreshLayout.setRefreshing(false);
break;
case FINISHED:
//Reached end of Data set
mSwipeRefreshLayout.setRefreshing(false);
break;
case ERROR:
retry();
break;
}
}
@Override
protected void onError(@NonNull Exception e) {
super.onError(e);
mSwipeRefreshLayout.setRefreshing(false);
}
};
recyclerView.setAdapter(mAdapter);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mAdapter.refresh();
}
});
The problem in your code is the fact that the type of your timestamp field inside your UserLight
class dosn't match the type of your timestamp
property in the database. See, in your UserLight
class the timestamp field is of type long
, which is basically a number while in the database is of type Date
or Timestamp
. Please note that both must match.
Because the correct way of holding dates in Cloud Firestore is to use the Date
or Timestamp
class, to solve this, simply change type of your timestamp field in your model class to be Date
, as explained in my answer from the following post: