我目前正在为一个出租的移动应用程序进行聊天。目前,我已将我的应用程序与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>() {
...