我目前正在为一个出租的移动应用程序进行聊天。目前,我已将我的应用程序与Cloud Firestore链接在一起,一旦他们注册,我便能够发送和接收来自不同用户的消息!

目前无法破解的问题是,我试图用发送者/接收者已发送或接收的消息填充此chatFragment.java类。我相信我的工作是正确的,但是当我尝试查询快照时,它总是说我需要将其声明为“ Executor”。

任何帮助都会很棒!干杯!

chatFragment.java

public class chatFragment extends Fragment {

    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private RecyclerView recyclerView;
    private userAdapter userAdapter;
    private List<User> mUsers;

    private FirebaseUser firebaseUser;
    private CollectionReference notebookRef ;

    private List<String> userList;

    public chatFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =  inflater.inflate(R.layout.fragment_chat, container, false);


        recyclerView = view.findViewById(R.id.chat_view_recycler);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));


        firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

        userList = new ArrayList<>();

        notebookRef = db.collection("Chats");



> notebookRef.addSnapshotListener( chatFragment.this, new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

                userList.clear();
                if(!documentSnapshots.isEmpty())
                {
                    for(DocumentChange doc:documentSnapshots.getDocumentChanges())
                    {
                        Chat obj = doc.getDocument().toObject(Chat.class);

                        if(obj.getSender().equals(firebaseUser.getUid()))
                        {
                            userList.add(obj.getReceiver());
                        }
                        if(obj.getReceiver().equals(firebaseUser.getUid()))
                        {
                            userList.add(obj.getSender());
                        }

                    }

                    readChats();
                }
            }
        });

        return view;
    }

    private void readChats() {

        mUsers = new ArrayList<>();

        notebookRef = db.collection("Chats");

        notebookRef.addSnapshotListener((Executor) chatFragment.this, new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

                userList.clear();


                for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {
                    User obj = doc.getDocument().toObject(User.class);

                    for (String id : userList) {
                        if (obj.getUserName().equals(id)) {
                            if (mUsers.size() != 0) {
                                for (User userUI : mUsers) {
                                    if (!obj.getUserName().equals(userUI.getUserName())) {
                                        mUsers.add(obj);
                                    }
                                }
                            } else {
                                mUsers.add(obj);
                            }
                        }
                    }
                }

                Query query = notebookRef.orderBy("userId", Query.Direction.DESCENDING);
                FirestoreRecyclerOptions<User> options = new FirestoreRecyclerOptions.Builder<User>()
                        .setQuery(query, User.class)
                        .build();
                userAdapter = new userAdapter(options);
                recyclerView.setAdapter(userAdapter);
            }
        });

    }
}


消息适配器

public class userAdapter extends FirestoreRecyclerAdapter<User,userAdapter.UserViewHolder> {

    public userAdapter( FirestoreRecyclerOptions<User> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull UserViewHolder holder,final int position, @NonNull User model) {
        holder.list_studentNumber.setText(model.getStudentNumber());
        holder.list_userName.setText(model.getUserName());
        holder.list_admin.setText(String.valueOf(model.isAdmin()));
        Picasso.get().load(model.getPhotoUrl()).fit().centerCrop().into(holder.list_photo);
        Log.d("USERIDaaaaa", model.getUserName());

    }



    @NonNull
    @Override
    public UserViewHolder onCreateViewHolder( @NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.format_users_value, parent, false);
        return new UserViewHolder(v);
    }

    class UserViewHolder extends RecyclerView.ViewHolder {

        TextView list_admin;
        ImageView list_photo;
        TextView list_studentNumber;
        TextView list_userName;

        public UserViewHolder(final View itemView) {
            super(itemView);

            list_admin = itemView.findViewById(R.id.list_admin);
            list_photo = itemView.findViewById(R.id.list_photo);
            list_studentNumber = itemView.findViewById(R.id.list_studentNumber);
            list_userName = itemView.findViewById(R.id.list_userName);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(itemView.getContext(), message_between_users.class);
                    itemView.getContext().startActivity(intent);
                }
            });
        }
    }
}


User.java


public class Chat implements Serializable {

        private String sender;
        private String receiver;
        private String message;
        private String Type;
        private Date Time;




    public Chat() {
            //empty constructor needed
        }

        public Chat(String sender, String receiver, String message, Date Time, String Type ) {
            this.sender = sender;
            this.receiver = receiver;
            this.message = message;
            this.Time = Time;
        }

        public String getSender() {
            return sender;
        }

        public void setSender(String sender) {
            this.sender = sender;
        }

        public String getReceiver() {
            return receiver;
        }

        public void setReceiver(String receiver) {
            this.receiver = receiver;
        }

        public String getType() { return Type; }

        public void setType(String type) { Type = type; }

        public Date getTime() { return Time; }

        public void setTime(Date time) { Time = time; }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }
    }



运行时错误信息

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.clubapp, PID: 28835
    java.lang.ClassCastException: com.example.clubapp.chatFragment cannot be cast to java.util.concurrent.Executor
        at com.example.clubapp.chatFragment.onCreateView(chatFragment.java:65)

最佳答案

addSnapshotListener的三个重载带有两个参数:


addSnapshotListener(Activity activity, EventListener<QuerySnapshot> listener)
addSnapshotListener(MetadataChanges metadataChanges, EventListener<QuerySnapshot> listener)
addSnapshotListener(Executor executor, EventListener<QuerySnapshot> listener)


这些重载都不将Fragment作为其第一个参数,因此编译器不知道要调用什么重载。

您可能正在尝试调用第一个重载,以便侦听器成为活动的作用域。但是在那种情况下,您需要传递活动,而不是片段。

实际上还允许将侦听器自动确定片段的范围是一个有趣的想法,因此您可能需要file a feature request



除非您需要控制Firebase运行其网络和磁盘I / O的线程,否则通常无需将执行程序传递给侦听器。在所有其他情况下,请像这样为您附加侦听器:

notebookRef.addSnapshotListener(new EventListener<QuerySnapshot>() {
  ...

10-01 03:10