按 T​​imeStamp 升序排列 Firestore 数据

Posted

技术标签:

【中文标题】按 T​​imeStamp 升序排列 Firestore 数据【英文标题】:Order Firestore data by TimeStamp in Ascending order 【发布时间】:2018-10-17 21:01:02 【问题描述】:

我将应用程序发布的想法存储在 Firestore 中。数据像 Ideas/documentID/IdeaObject 一样存储在 Firestore 中。问题是当我检索数据时,它没有按发布时间排序。检索到的想法是根据 Firestore 自动创建的 documentID 的 id。我在我的模型类中使用了 ServerTimestamp,当我检索它时,我将 orderBy 方法与我的 Firestore 引用一起使用,但仍然没有。

Idea.java

public class Idea 
    @ServerTimestamp
    private Date date;
    private String title, idea, timeCommitment, ideaStage, postedBy, website, videoPitch;
    private int views, favorites;
    private ArrayList<String> lookingFor = new ArrayList<>();
    private ArrayList<String> tags = new ArrayList<>();
    private String userID;
    private String timeStamp;

    public Idea() 
    

    public Idea(String title, String idea, String timeCommitment, String ideaStage, String postedBy, String website, String videoPitch, int views, int favorites, ArrayList<String> lookingFor, ArrayList<String> tags, String userID, String timeStamp) 
        this.title = title;
        this.idea = idea;
        this.timeCommitment = timeCommitment;
        this.ideaStage = ideaStage;
        this.postedBy = postedBy;
        this.website = website;
        this.videoPitch = videoPitch;
        this.views = views;
        this.favorites = favorites;
        this.lookingFor = lookingFor;
        this.tags = tags;
        this.userID = userID;
        this.timeStamp = timeStamp;
    

创意发布方式

  private void postIdea() 

        final String ideaID = UUID.randomUUID().toString();
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());


        Idea ideas = new Idea(title, idea, timeCommitment, ideaStage, AppValues.fullName, website, videoPitch, 0, 0, lookingFor, tags, AppValues.userId, "" + timestamp.getTime());

        firestoreDb.collection("ideas")
                .document(ideaID)
                .set(ideas)
                .addOnSuccessListener(new OnSuccessListener<Void>() 
                    @Override
                    public void onSuccess(Void aVoid) 
                        postIdeaUser(ideaID);
                    
                )
                .addOnFailureListener(new OnFailureListener() 
                    @Override
                    public void onFailure(@NonNull Exception e) 
                        hideLoadingDialog();
                        showToast(e.getMessage());
                    
                );
    

按时间检索所有创意

   firestoreDb.collection("ideas")
                .orderBy("timeStamp", Query.Direction.ASCENDING)
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() 
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) 
                        if (task.isSuccessful()) 

                            ideaArrayList = new ArrayList<>();
                            ideaArrayList.clear();

                            for (DocumentSnapshot documentSnapshot : task.getResult()) 
                                Idea idea = documentSnapshot.toObject(Idea.class);
                                if (!idea.getUserID().equals(AppValues.userId)) 
                                    ideaArrayList.add(idea);
                                
                            

                            callAdapter();

                         else 
                            Log.d(TAG, "Error getting documents: ", task.getException());
                            progressBar.setVisibility(View.GONE);
                            swipeRefresh.setEnabled(true);
                            errorText.setVisibility(View.VISIBLE);
                        
                    
                ); 

我想要实现的是检索所有想法并让它们按 TimeStamp 值升序排列。

【问题讨论】:

你为什么要同时存储一个名为 date 并带有 @ServerTimestamp 注释的字段和一个格式化的 timeStamp 字符串?似乎您只需要 @ServerTimestamp 值,并让您的查询使用它。 @DougStevenson 您能否指定如何在查询中使用 serverTimestamp 值?我在检索 data.orderBy("date", Query.Direction.ASCENDING) 时尝试使用它,但仍然没有。 我希望它可以工作。 “无”是什么意思? task.getException() 会返回什么吗? 【参考方案1】:

在查询数据库时不能使用字符串 (timeStamp) 而不是日期 (date) 并期望其行为与日期相同。所以要解决这个问题,请更改以下代码行:

firestoreDb.collection("ideas")
            .orderBy("timeStamp", Query.Direction.ASCENDING)

firestoreDb.collection("ideas")
            .orderBy("date", Query.Direction.ASCENDING)

为了使它工作,这种查询需要一个索引。要创建一个,请查看我在以下帖子中的回答:

Firestore whereEqualTo, orderBy and limit(1) not working

【讨论】:

我使用长类型时间戳仍然没有得到想要的结果。 @AnkitMishra 您需要使用Firestore Timestamp,而不是长值。 我刚刚创建了索引,它与我想要的时间戳完美配合。感谢您的帮助。 顺便说一句,我必须说你在火力基地的事情上很摇滚。? @AnkitMishra 也许这个approach 会有所帮助。【参考方案2】:

在我的情况下,香草版本是,

firestoreDb.collection("ideas")
     .orderBy("timestamp", "asc")

firestoreDb.collection("ideas")
     .orderBy("timestamp", "desc")

“ideas”是你的收藏名称

“时间戳”是用于排序的键或字段或列名。

“asc”或“desc”是用于订单的选项

【讨论】:

【参考方案3】:

您还必须在数据库中的 Firebase 帐户中添加索引 -> 索引 -> 添加索引

【讨论】:

你的意思是不在代码中?【参考方案4】:

只需创建索引,它也将开始使用时间戳。只要确保时间戳是数字类型而不是字符串即可。

创建索引的最佳方法是在 android Studio logcat 中搜索 FAILED_PRECONDITION:,您将看到一个链接,只需点击该链接并创建索引。 示例:FAILED_PRECONDITION: The query requires an index. You can create it here: ...

如有任何疑问,请随时提出。

【讨论】:

创建索引是什么意思?另外,您如何实现该索引? 我的意思是数据库索引。 是在 kotlin 代码中完成的吗?【参考方案5】:

您可以按照以下步骤在控制台上订购您的 Firebase 数据。

第 1 步:单击文档集合中的这三行。

第 2 步:从那里,您将获得要作为过滤依据的字段。您输入任何字段,在我的例子中是“时间戳”。

第 3 步: 选择您要应用的排序结果,在我的情况下是“asc”,然后单击应用,它应该在数据库中排序您想要的结果。 p>

【讨论】:

以上是关于按 T​​imeStamp 升序排列 Firestore 数据的主要内容,如果未能解决你的问题,请参考以下文章

XQuery 按升序和降序排列

MongoDB按“数字”升序排列

MongoDB按“数字”升序排列

alpha 对具有相同整数值且应按升序排列的列表进行排序[重复]

对一个 n 元素数组进行排序,使前 k 个元素按升序排列最低(就地算法)

DataTable 升序排列日期