【问题标题】:Error in getting server timestamp in Firestore在 Firestore 中获取服务器时间戳时出错
【发布时间】:2019-08-20 17:01:12
【问题描述】:

我正在尝试在 Cloud Firestore 中添加文档,但我需要服务器 timestamp 来添加文档。使用正确的timestamp 将文档成功添加到集合中。我正在添加带有警报对话框的文档。但是当我返回我的活动时,应用程序终止并出现以下错误:

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException ........ E/AndroidRuntime: 引起:java.lang.NullPointerException:尝试调用虚拟 方法'java.util.Date com.google.firebase.Timestamp.toDate()' 空对象引用 在 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);

我的课来了

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();
            }
        });

插入后的文档

【问题讨论】:

  • 处理来自查询的快照的代码是什么?添加的文档到底是什么样的?
  • @DougStevenson 我正在使用FirestorePagingAdapter。我已经编辑了我的问题..你能检查一下吗?

标签: java android firebase google-cloud-firestore firebaseui


【解决方案1】:

代码中的问题是UserLight 类中时间戳字段的类型与数据库中timestamp 属性的类型不匹配。看,在您的UserLight 类中,时间戳字段的类型为long,它基本上是一个数字,而数据库中的类型为DateTimestamp。请注意,两者必须匹配。

因为在 Cloud Firestore 中保存日期的正确方法是使用 DateTimestamp 类,要解决此问题,只需将模型类中时间戳字段的类型更改为 Date,如在我在以下帖子中的回答:

【讨论】:

  • 有时应用程序会因以下错误而终止 java.lang.IllegalArgumentException: Invalid query。您正在尝试使用字段“additionTime”是未提交的服务器时间戳的文档开始或结束查询。 (因为这个字段的值是未知的,所以你不能用它开始/结束查询。)
  • 这听起来是另一个问题。因此,请使用自己的MCVE 发布另一个新问题,以便我和其他 Firebase 开发人员可以帮助您。
猜你喜欢
  • 2018-11-27
  • 2021-04-19
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 2018-03-20
相关资源
最近更新 更多