Firestore如何在回收者视图中从Firestore检索数据

时间:2019-03-16 19:43:42

标签: android firebase google-cloud-firestore

背景

我的应用程序允许用户发布特定类别的图像,然后允许用户点击这些帖子以显示消息活动

问题

我目前已对其进行设置,因此它是一个全局聊天(任何用户都可以加入,并且在同一文档中读写的所有帖子之间都是相同的),用于测试目的,但是我想拥有它,因此它是私人聊天在两个用户之间。这是使用我正在迁移到Firestore的实时数据库创建的,因此我还必须更改“ chatActivity”的代码

我做了什么

创建帖子后,它将向该帖子的消息集合中添加一个新文档。与该帖子关联的消息文档名称随后存储在该帖子中。

我被困在哪里

在聊天活动中,我需要能够获取帖子的ID,以便随后检索包含与该帖子相关的消息的文档的位置

客观

要能够使用户发布图像并在“消息”集合中创建文档,请完成,然后让第二个用户来查看该图像,然后打开该文档。是为图片创建的,因此两个用户之间可以互相交换消息,从而在两个用户之间将消息设为私有,因为他们仅从与该帖子关联的文档中进行读取

app workflow,这应该可以消除所有的困惑

数据库:database

将帖子写到数据库的代码:

filePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                                @Override
                                public void onSuccess(Uri uri) {
                                    final String downloadUrl =
                                            uri.toString();
                                    Log.d("tag", downloadUrl);

                                    FirebaseUser current_user = FirebaseAuth.getInstance().getCurrentUser();
                                    String uid = Objects.requireNonNull(current_user).getUid();

                                    final Map<String, Object> postMap = new HashMap<>();
                                    // No thumb ?????
                                    postMap.put("image_url", downloadUrl);
                                    postMap.put("desc", desc);
                                    postMap.put("user_id", current_user_id);
                                    postMap.put("message Doc", uid + postCategory);
                                    postMap.put("timestamp", FieldValue.serverTimestamp());


                                    firebaseFirestore.collection(postCategory).add(postMap).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
                                        @Override
                                        public void onComplete(@NonNull Task<DocumentReference> task) {

                                            if (task.isSuccessful()) {

                                                firebaseFirestore.collection("Posts").add(postMap).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
                                                    @Override
                                                    public void onComplete(@NonNull Task<DocumentReference> task) {

                                                        FirebaseUser current_user = FirebaseAuth.getInstance().getCurrentUser();
                                                        String uid = Objects.requireNonNull(current_user).getUid();

                                                        final Map<String, String> chatMap = new HashMap<>();
                                                        postMap.put("timestamp", FieldValue.serverTimestamp());
                                                        postMap.put("name", current_user_id);
                                                        postMap.put("message", "");

                                                        firebaseFirestore.collection("Messages")
                                                                .document(uid + postCategory)
                                                                .set(chatMap)
                                                                .addOnSuccessListener(new OnSuccessListener<Void>() {
                                                                    @Override
                                                                    public void onSuccess(Void aVoid) {

                                                                    }
                                                                });

聊天代码

public class ChatActivity extends AppCompatActivity {

    public static final int DEFAULT_MSG_LENGTH_LIMIT = 1000;
    private static final int GALLERY_PICK = 1;

    private ListView mMessageListView;
    private MessageAdapter mMessageAdapter;// This is to do with the file messageadapter\
    private ProgressBar mProgressBar;
    private ImageButton mPhotoPickerButton;
    private EditText mMessageEditText;
    private Button mSendButton;
    private String mUsername;
    private FirebaseDatabase mFirebaseDatabase;
    private DatabaseReference mMessagedatabaseReference;
    private ChildEventListener mChildEventListner;
    private ValueEventListener mValueEventListner;
    private FirebaseUser mCurrentUser;
    private FirebaseStorage mFirebaseStorage;
    private ProgressDialog mProgressDialog;
    private StorageReference mChatPhotosStorageReference;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chat_activity);

        mFirebaseDatabase = FirebaseDatabase.getInstance();
        mMessagedatabaseReference = mFirebaseDatabase.getReference().child("messages");


        //new shit

        // Map<String, Object> usersChat = new HashMap<>();
        // usersChat.put("user 1 id", mCurrentUser);
        // usersChat.put("user2Id", )





        mFirebaseStorage = FirebaseStorage.getInstance();
        mChatPhotosStorageReference = mFirebaseStorage.getReference().child("chat_photos");

        // Initialize references to views
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
        mMessageListView = (ListView) findViewById(R.id.messageListView);
        mPhotoPickerButton = (ImageButton) findViewById(R.id.photoPickerButton);
        mMessageEditText = (EditText) findViewById(R.id.messageEditText);
        mSendButton = (Button) findViewById(R.id.sendButton);

        mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
        final String current_uid = mCurrentUser.getUid();

        // Initialize progress bar
        mProgressBar.setVisibility(ProgressBar.INVISIBLE);

        //Initialize message ListView and its adapter
        List<FriendlyMessage> friendlyMessages = new ArrayList<>();
        mMessageAdapter = new MessageAdapter(this, R.layout.item_message, friendlyMessages);
        mMessageListView.setAdapter(mMessageAdapter);

        // ImagePickerButton shows an image picker to upload a image for a message
        mPhotoPickerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent galleryIntent = new Intent();
                galleryIntent.setType("image/*");
                galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

                startActivityForResult(Intent.createChooser(galleryIntent, "Select Image"), GALLERY_PICK);
            }
        });

        // Enable Send button when there's text to send
        mMessageEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (charSequence.toString().trim().length() > 0) {
                    mSendButton.setEnabled(true);
                } else {
                    mSendButton.setEnabled(false);
                }
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });
        mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(DEFAULT_MSG_LENGTH_LIMIT)});

        // Send button sends a message and clears the EditText
        mSendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString());
                mMessagedatabaseReference.push().setValue(friendlyMessage);

                // Clear input box
                mMessageEditText.setText("");
            }
        });

        mChildEventListner = new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                FriendlyMessage friendlyMessage = dataSnapshot.getValue(FriendlyMessage.class);
                mMessageAdapter.add(friendlyMessage);

            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        };
        mMessagedatabaseReference.addChildEventListener(mChildEventListner);

        mSendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString(), current_uid, null);
                mMessagedatabaseReference.push().setValue(friendlyMessage);

                // Clear input box
                mMessageEditText.setText("");
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == GALLERY_PICK && resultCode == RESULT_OK) {

            Uri selectedImageUri = data.getData();

            final StorageReference photoRef = mChatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());

            photoRef.putFile(selectedImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    photoRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                        @Override
                        public void onSuccess(Uri uri) {
                            String downloadUrl = uri.toString();
                            Log.d("tag", downloadUrl);
                            FriendlyMessage friendlyMessage = new FriendlyMessage(null, mUsername, downloadUrl);
                            mMessagedatabaseReference.push().setValue(friendlyMessage);
                        }
                    });
                }
            });

        }
    }

2 个答案:

答案 0 :(得分:0)

  

我被困在哪里

     

在我的聊天活动中,我需要能够获取帖子的ID ,因此我   然后可以检索包含消息的文档的位置   与该帖子有关

我不确定,您要获取所有ID还是仅获取一个ID?

如果您要从Firestore获取id集合的 ALL music个文档,请在您的代码中添加此文件:

public void loadAlltQueries(){
 Query loadAllQueryId = firebaseFirestore
                       .collection("music")
                       .orderBy("timestamp", Query.Direction.DESCENDING);

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


     for (DocumentChange doc : documentSnapshots.getDocumentChanges()){

       if (doc.getType() == DocumentChange.Type.ADDED){

          String musicId = doc.getDocument().getId();
          FriendlyMessage friendlyMessage = doc.getDocument().toObject(FriendlyMessage.class).withId(musicId);                        

          mMessageAdapter.add(friendlyMessage);                                                                       

          mMessageAdapter.notifyDataSetChanged(); //for update adapter
        }
     }

    }
  });
}

并制作 MusicId.class

public class MusicId{

    @Exclude
    public String MusicId;

    public <T extends MusicId> T withId(@NonNull final String id) {

        this.MusicId = id;
        return (T) this;
    }

}

不要忘记在您的 FriendlyMessage.class

中添加它
public class FriendlyMessage extends MusicId {

// your constructor
// your getter

}

从适配器类中获取您的吸气剂

 final String musicId = contentList.get(position).MusicId;

现在您获得ID CHur40Nr ..

如果您要获取与从回收者视图中选择的任何帖子相对应的帖子ID。请设置适配器类,因为holder 方法将获取您选择的帖子 ,在本案例中为holder.setMessage(message);

public class AdapterFriendlyMessage extends RecyclerView.Adapter<FriendlyMessage.ViewHolder> {

    public List<FriendlyMessage> contentList;
    public Context context;

    private FirebaseFirestore firebaseFirestore;
    private FirebaseAuth firebaseAuth;

    public AdapterFriendlyMessage(List<FriendlyMessage> contentList){
        this.contentList = contentList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_friendly_message, parent, false);
        context = parent.getContext(); FriendlyMessage(container.getContext(), contentList);

        firebaseFirestore = FirebaseFirestore.getInstance();
        firebaseAuth = FirebaseAuth.getInstance();

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        holder.setRecyclable(false);

        // GET MusicId
        final String  musicId = contentList.get(position). MusicId;
        final String currentUserId = firebaseAuth.getCurrentUser().getUid();   


        String uid = contentList.get(position).getUid();
        firebaseFirestore.collection(" Music").document( musicId).collection("FriendlyMessage").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>(){
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task){

                if (task.isSuccessful()) {

                    String message = task.getResult().getString("message");
                    holder.setMessage(message); // this is what you want
                } 
            }
        });       
    }

    @Override
    public int getItemCount() {
        return contentList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private View mView;    

        private TextView txtMessage;           

        public ViewHolder(View itemView){
            super(itemView);
            mView = itemView;   

        }

            public void setMessage(Sting text) {

                txtMessage = mView.findViewById(R.id.text_view_mesage);
                txtMessage.setText(text);
            }


    }
}

不要忘记将id从Firestore传递到适配器 公共类FriendlyMessageRoom扩展了片段{

private RecyclerView recyclerMessage;
private List<FriendlyMessage > contentList;
private AdapterFriendlyMessage adapterFriendlyMessage;        

private FirebaseFirestore firebaseFirestore;
private FirebaseAuth mAuth;



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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_friendly_message_room, container, false);


    mAuth = FirebaseAuth.getInstance();
    firebaseFirestore = FirebaseFirestore.getInstance();

    contentList = new ArrayList<>();
    recyclerMessage = view.findViewById(R.id.recycler_message);
    adapterFriendlyMessage = new AdapterFriendlyMessage(contentList);
    recyclerMessage.setLayoutManager(new LinearLayoutManager(container.getContext()));
    recyclerMessage.setAdapter(adapterFriendlyMessage);

    return view;
}

@Override
public void onStart() {
    super.onStart();

    loadAlltQueries(); // please see firebase query that i write above
}

注意:我的这个答案可能无法准确回答您的问题,因为很难想象您在问题描述中想要什么。

答案 1 :(得分:0)

停止强调自己编写这些样板,以便从Firestore到Recycler视图中检索数据。查看Cloud Firestore的Firebase UI。 Cloud Firestore的Firebase UI使将Cloud Firestore的数据绑定到应用程序的UI变得很简单,从而减少了样板,甚至可能有助于解决问题。将此实现“ com.firebaseui:firebase-ui-firestore:6.2.1”添加到依赖项以将Firebase UI用于Cloud Firestore