在 Firestore 中获取服务器时间戳时出错
Error in getting server timestamp in Firestore
我正在尝试在 Cloud Firestore 中添加文档,但我需要服务器 timestamp
来添加文档。文档已成功添加到集合中且 timestamp
正确。我正在添加带有警告对话框的文档。但是,当我返回我的 activity 应用程序时,它因以下错误而终止:
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)
为了显示文档,我正在使用以下查询
Query query= FirebaseFirestore.getInstance()
.collection("Users")
.document(user.getUid())
.collection("friends")
.orderBy("timestamp", Query.Direction.DESCENDING);
我的class在这里
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();
}
}
处理查询快照的代码
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();
}
});
文档插入后
您的代码中的问题是 UserLight
class 中的时间戳字段类型与 timestamp
属性 中的类型不匹配在数据库中。看,在您的 UserLight
class 中,时间戳字段是 long
类型,它基本上是一个数字,而在数据库中是 Date
或 Timestamp
类型。请注意两者必须匹配。
因为在 Cloud Firestore 中保存日期的正确方法是使用 Date
或 Timestamp
class,要解决这个问题,只需更改模型中时间戳字段的类型class 为 Date
,正如我在以下 post:
的回答中所解释的
我正在尝试在 Cloud Firestore 中添加文档,但我需要服务器 timestamp
来添加文档。文档已成功添加到集合中且 timestamp
正确。我正在添加带有警告对话框的文档。但是,当我返回我的 activity 应用程序时,它因以下错误而终止:
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)
为了显示文档,我正在使用以下查询
Query query= FirebaseFirestore.getInstance()
.collection("Users")
.document(user.getUid())
.collection("friends")
.orderBy("timestamp", Query.Direction.DESCENDING);
我的class在这里
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();
}
}
处理查询快照的代码
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();
}
});
文档插入后
您的代码中的问题是 UserLight
class 中的时间戳字段类型与 timestamp
属性 中的类型不匹配在数据库中。看,在您的 UserLight
class 中,时间戳字段是 long
类型,它基本上是一个数字,而在数据库中是 Date
或 Timestamp
类型。请注意两者必须匹配。
因为在 Cloud Firestore 中保存日期的正确方法是使用 Date
或 Timestamp
class,要解决这个问题,只需更改模型中时间戳字段的类型class 为 Date
,正如我在以下 post: