【问题标题】:Using firebase firestore for chat with unique messages使用 firebase firestore 与独特的消息聊天
【发布时间】:2020-08-09 17:49:44
【问题描述】:

我创建了一个包含聊天的应用程序。

我正在使用 Firebase firestore 来存储消息并为用户显示它们。

聊天如下:

但是,如果其中一个用户点击应用程序中的某个按钮,另一个用户会收到一条独特的消息,其中显示一些信息和一个按钮作为消息的一部分,如下所示:

只有收到该消息的用户之一才能看到此消息。

问题描述:

为了在聊天中显示消息,我在 firestore 中阅读了一个包含所有消息的集合。当发送一条独特的消息时,它也会被添加到集合中,因此我需要做大量的 if 条件和其他操作,以确保只有一个用户会看到它而不是另一个 - 这在我看来非常复杂,我正在寻找一些更简单的方法来控制某些消息将如何仅显示给其中一个用户。

目前,我通过以下方式获取消息:

public void getChats(String chatID, long messageIndex, EventListener<QuerySnapshot> listener) {

    Query lastMessages;

    if (messageIndex != 0) {
        lastMessages = db.collection( chatID )
                .orderBy( "SentTime", Query.Direction.DESCENDING ).startAfter( messageIndex ).limit( 50 );
    } else {
        lastMessages = db.collection( chatID )
                .orderBy( "SentTime", Query.Direction.DESCENDING ).limit( 50 );
    }

    lastMessages.addSnapshotListener( listener );

}

然后我调用适配器来处理视图:

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        if (viewType == AppConstants.CHAT_SENT_KEY) {
            view = LayoutInflater.from( parent.getContext() ).inflate(
                    R.layout.item_chat_sent,
                    parent,
                    false );
            return new ChatViewHolder( view );

        } else if (viewType == AppConstants.CHAT_RECEIVED_KEY) {
            view = LayoutInflater.from( parent.getContext() ).inflate(
                    R.layout.item_chat_received,
                    parent,
                    false );
            return new ChatViewHolder( view );

        } else {
            view = LayoutInflater.from( parent.getContext() ).inflate( R.layout.item_loading, parent, false );
            return new LoadingViewHolder( view );
        }

    }
    
    
    @Override
    public int getItemViewType(int position) {
        if (chats.get( position ).getSenderId().contentEquals( userId )) {
            if (position == 0 && chats.size() > 49 && snapSize > 49) {
                return AppConstants.CHAT_LOADING_KEY;
            } else {
                return AppConstants.CHAT_SENT_KEY;
            }
        } else {
            if (position == 0 && chats.size() > 49 && snapSize > 49) {
                return AppConstants.CHAT_LOADING_KEY;
            } else {
                return AppConstants.CHAT_RECEIVED_KEY;
            }
        }
    }

    @Override
    public int getItemCount() {
        return chats == null ? 0 : chats.size();
    }

    class ChatViewHolder extends RecyclerView.ViewHolder {
        TextView message, messageTime;
        Button confirmShare;

        public ChatViewHolder(View itemView) {
            super( itemView );

            message = itemView.findViewById( R.id.chat_message );
            messageTime = itemView.findViewById( R.id.time_message );
            confirmShare = itemView.findViewById( R.id.Confirm_Share );
        }

        public void bind(Chat chat) {

        ArrayList Index = new ArrayList();
        ArrayList IndexConfirmed = new ArrayList();

        message.setText( chat.getMessage() );

        Date date = new Date( chat.getTime() );

        String TimeFormat = "dd.MM.yyyy 'at' HH:mm";
        SimpleDateFormat df2 = new SimpleDateFormat( TimeFormat );
        String dateText = df2.format( date );
        messageTime.setText( dateText );

        for (int i = 0; i < chats.size(); i++) {
            if (chats.get( i ).getIsButton()) {
                Index.add( i );
                if (chats.get( i ).getMessage().equals( "YOU CONFIRMED" )) {
                    IndexConfirmed.add( i );
                }
            }
        }
        if (Index.isEmpty()) {
            Index.add( -1 );
        }
        if (IndexConfirmed.isEmpty()) {
            IndexConfirmed.add( -2 );
        }

        int LastInd = (int) Collections.max( Index );
        int LastIndConfirmed = (int) Collections.max( IndexConfirmed );

        if (!chats.get( getAdapterPosition() ).getSenderId().contentEquals( userId )) {
            if (LastInd > LastIndConfirmed && getAdapterPosition() == LastInd && chat.getIsButton()) {
                confirmShare.setVisibility( View.VISIBLE );
                confirmShare.setOnClickListener( v -> confirmListener.onClick( btn_ConfirmButton ) );
            } else {
                confirmShare.setVisibility( View.GONE );
            }
        } else {
            if (chat.getIsButton()) {
                message.setVisibility( View.GONE );
                messageTime.setVisibility( View.GONE );
            }
        }

    }

}

是否有任何其他方法可以控制每个用户可以看到哪些消息,即使我从 firestore 读取了所有消息以显示它们?

谢谢

【问题讨论】:

  • 我想你可能对这个Firestore Chat App感兴趣。
  • 嘿,谢谢,会看的。没有看到它除了发送/阅读消息之外还有其他类型(除非我错过了什么)。

标签: java android firebase google-cloud-firestore


【解决方案1】:

好的,我认为您需要在此处修改您的架构。从技术上讲,请求不是文本消息,而是可以将其视为请求消息并进行字符串检查以检查这是一种非常糟糕的做法。

为什么不为每个不同的消息类型创建消息类,并将它们包含在您的聊天对象模型中。 当您循环浏览它们时,您可以简单地检查其类型,然后从那里您只能在发件人是对方时显示它。

我会像这样为我的课程建模:

包含:日期,发件人,(isRead 也将 是一个很好的功能)

TextMessage 类扩展 Message 并且还包含一个字符串 对于文本

RequestMessage 类也扩展了 Message 并包含 isConfirmed 变量。

【讨论】:

    猜你喜欢
    • 2019-08-14
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 2020-11-30
    • 2019-01-19
    • 2020-09-10
    相关资源
    最近更新 更多