首页 > 解决方案 > Android Firestore 将限制设置为每位用户 1 票

问题描述

我正在从头开始创建我的第一个应用程序,它是 android 上的一个论坛应用程序,我已经了解了它的赞成/反对部分。

我将它设置为我的用户可以投票反对的地方(类似于 StackOverflow)但是我不知道如何将其限制为每个用户一票。

我使用 Firebase-Firestore 作为数据库。

我设置了 upvote 和 downvote 切换按钮,以在按钮单击侦听器上更新 firestore 中的分数,并为每个按钮添加各自的选择器item.xml

任何人都可以阐明将用户限制为每个用户每个答案一票的方法,类似于堆栈溢出?

任何和所有的帮助表示赞赏。

编辑

尝试提供答案之前的当前代码。

应答适配器

public class AnswerAdapter extends FirestoreRecyclerAdapter<Answer, AnswerAdapter.AnswerHolder> {

    private QuestionAdapter.OnItemClickListener listener;
    private Context mContext;
    private static final String TAG = "AnswerAdapter";

    /**
     * Create a new RecyclerView adapter that listens to a Firestore Query.  See {@link
     * FirestoreRecyclerOptions} for configuration options.
     *
     * @param options
     */

    public AnswerAdapter(@NonNull FirestoreRecyclerOptions<Answer> options) {

        super(options);
    }

    @NonNull
    @Override
    public AnswerHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.answer_item, viewGroup, false);
        return new AnswerHolder(v);
    }

    @Override
    protected void onBindViewHolder(@NonNull final AnswerAdapter.AnswerHolder answerHolder, final int position, @NonNull final Answer model) {

        answerHolder.answerItemTextView.setText(model.getAnswer());
        answerHolder.answerAuthorTextView.setText(model.getAuthor());
        answerHolder.answerTimeStampTextView.setText(model.getTimestamp());
        answerHolder.answerScoreTextView.setText(getSnapshots().getSnapshot(position).get("answerScore").toString());

        answerHolder.mAnswerUpVoteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO: 2019-07-26 check order of operations. seems to go through upvote and then also through downvote unchecking state
                if (answerHolder.mAnswerUpVoteButton.isChecked()){

                    answerUpVote(answerHolder, position, model);
                } else {
//                    answerDownVote(answerHolder, position, model);
                }
            }
        });

public class AnswerHolder extends RecyclerView.ViewHolder{

        TextView answerItemTextView;
        TextView answerScoreTextView;
        ToggleButton answerCheckMark;
        TextView answerAuthorTextView;
        TextView answerTimeStampTextView;
        ToggleButton mAnswerUpVoteButton;
        ToggleButton mAnswerDownVoteButton;


        public AnswerHolder(@NonNull final View itemView) {
            super(itemView);
            answerItemTextView = itemView.findViewById(R.id.answerItemTextViewId);
            answerScoreTextView = itemView.findViewById(R.id.questionScoreId);
            answerCheckMark = itemView.findViewById(R.id.answerCheckMarkId);
            answerAuthorTextView = itemView.findViewById(R.id.answerAuthorTextViewId);
            answerTimeStampTextView = itemView.findViewById(R.id.answerTimeStampTextViewId);
            mAnswerUpVoteButton = itemView.findViewById(R.id.answerUpVoteId);
            mAnswerDownVoteButton = itemView.findViewById(R.id.answerDownVoteId);

            mContext = itemView.getContext();

        }

    }

private void answerUpVote(@NonNull final AnswerAdapter.AnswerHolder answerHolder, final int position, @NonNull final Answer model) {
        final String answerScoreFBValue = getSnapshots().getSnapshot(position).get("answerScore").toString();
        final String answerFirebaseIdString = getSnapshots().getSnapshot(position).get("answerFirebaseId").toString();
//        Toast.makeText(mContext, "upvote button clicked " + answerScoreFBValue, Toast.LENGTH_SHORT).show();
        final CollectionReference answerCollectionRef = FirebaseFirestore.getInstance().collection("Answers");
        final DocumentReference answerDocRef = answerCollectionRef.document(answerFirebaseIdString);


        answerDocRef.update("answerScore", FieldValue.increment(1)).addOnSuccessListener(new OnSuccessListener<Void>() {
            //                answerRef.document().update("answerscore", answerScoreTestInt).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.d(TAG, "onSuccess: answerScore incremented");
//                answerHolder.answerScoreTextView.setText("testing");

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.e(TAG, "onFailure: answerScore was not incremented", e);
            }
        });
    }

答案.java

package com.example.stairmaster.models;

public class Answer {

    private String answer;
    private String comment; 
    private String timestamp;
    private int answerScore;
    private String author;
    private String answerFirebaseId;
    private String parentQuestionId;


    public Answer(String answer, String timeStamp, String author, String parentQuestionId, int answerScore) {

        this.answer = answer;
        this.timestamp = timeStamp;
        this.answerScore = answerScore;
        this.author = author;
        this.parentQuestionId = parentQuestionId;
    }

    public Answer () {
        // public no-arg constructor needed
    }

    public String getAnswerFirebaseId() {
        return answerFirebaseId;
    }

    public void setAnswerFirebaseId(String answerFirebaseId) {
        this.answerFirebaseId = answerFirebaseId;
    }

    public String getAnswer() {
        return answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    public int getAnswerScore() {
        return answerScore;
    }

    public void setAnswerScore(int answerScore) {
        answerScore = answerScore;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getParentQuestionId() {
        return parentQuestionId;
    }

    public void setParentQuestionId(String parentQuestionId) {
        this.parentQuestionId = parentQuestionId;
    }
}

标签: javaandroidgoogle-cloud-firestoreandroid-togglebutton

解决方案


您可能会考虑将您的 firebase 数据库中的数据库表修改为如下所示。

user_votes:
  - userid: 1234232 // A sample user id for your user
    - forumid: 8769765 // The id of the forum or blog
      - upvote: 1 // Number of upvotes in that specific forum/blog
      - downvote: 0 // Number indicates the downvote to that forum/blog
    - forumid: 1233432 
      - upvote: 1 
      - downvote: 0 
    - forumid: 8712169767 
      - upvote: 0 
      - downvote: 1 

另一个记录特定论坛/博客的赞成/反对记录的表格可能如下所示。

all_votes:
  - forumid: 8769765 // The id of the forum or blog
    - upvote: 9876 // Number of upvotes in that specific forum/blog
    - downvote: 123 // Number indicates the downvote to that forum/blog
  - forumid: 1233432 
    - upvote: 87 
    - downvote: 12 
  - forumid: 8712169767 
    - upvote: 112 
    - downvote: 10

现在,基于这两个表,您可以轻松地决定是否要setValue在表中发出命令以all_votes获取论坛 ID。如果发现用户已经发出了赞成票,则使应用程序逻辑不会在all_votes表中为该特定用户发出另一个赞成票。

希望有帮助!


推荐阅读