Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android Firestore将每个用户的投票限制为1票_Java_Android_Google Cloud Firestore_Android Togglebutton - Fatal编程技术网

Java Android Firestore将每个用户的投票限制为1票

Java Android Firestore将每个用户的投票限制为1票,java,android,google-cloud-firestore,android-togglebutton,Java,Android,Google Cloud Firestore,Android Togglebutton,我正在从头开始创建我的第一个应用程序,这是一个android上的论坛应用程序,我已经进入了向上投票/向下投票部分 我已经将它设置为我的用户可以向上投票或向下投票(类似于StackOverflow),但是我不知道如何将它限制为每个用户只能投一票 我正在使用Firebase Firestore作为数据库 我设置了upvote和downvote切换按钮,以更新firestore中按钮单击侦听器时的分数,并分别使用各自的选择器item.xml 有谁能解释一种类似于堆栈溢出的方法来限制用户对每个用户的每个

我正在从头开始创建我的第一个应用程序,这是一个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);
            }
        });
    }

我正在做一件类似的事情,我做这件事的方式是使用本地房间数据库。因此,首先,它检查本地数据库,看看用户是否可以投票。如果可以,则会向firestore发送更新相关字段的请求。我还使用了RxKotlin,并将返回的任务(从对firestore的请求)包装成一个可观察任务。如果observable完成时没有任何错误,那么它将更新本地数据库。如果它失败了,那么它什么也做不了。我确信还有其他方法,但这就是我选择的方法

> P>你可以考虑在FieldBasic数据库中修改数据库表,如下所示。p>
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
另一个保存特定论坛/博客的上升/下降投票记录的表格可能如下所示

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
现在,根据这两个表,您可以轻松决定是否要在论坛id的
all_votes
表中发出
setValue
命令。如果发现用户已经发出了upvote,然后,使应用程序逻辑不会在
all_votes
表中为该特定用户发出另一个upvote


希望有帮助

共享一些代码,这样我们可以更好地help@treewallie,稍后再做。目前在atm机上工作。你解决问题了吗?@Treewallie,为you@AlexMamo,还没有。不幸的是,我要到明天或本周晚些时候才能解决这个问题。谢谢你的建议,直到现在我才知道本地房间数据库。我看看能不能查一下,试试看。你知道它在Firestore中是否运行良好吗?如果你正确地实现它,它将运行良好。我将所有内容都包装到一个可观察对象中(从本地和远程数据库返回的任何内容)。Reaz的方法看起来也很好,但这是firestore的额外读取请求。但是我的方法会更复杂,因为你必须设置本地数据库。我有另一个想法,但它可能非常原始。我可以在答案模型中添加用户投票列表。例如,如果用户进行投票,则其唯一的用户id将添加到列表中。这样做可以让我跟踪谁投了赞成票或反对票。我可以使upvote或downvote成为一个点击按钮的侦听器,并检查答案中的投票人列表。如果存在匹配项,则不会让该用户投票两次。这份名单可以保存在firestore中。这听起来与您的方法类似,尽管它只使用Firestore。你认为呢?是的,它可以工作,但是如果你使用本地数据库,你就不需要额外的写/读请求(为你节省firestore的使用费/金钱)。另外,额外的网络呼叫只是更多的故障点。但最后,这取决于你,这种方法会奏效。谢谢你的提示。过去几天我一直在调查此事。很少有人将firestore与本地房间db一起使用。你有没有偶然发现有人使用这两种方法的好例子?谢谢你的建议,我会尝试一下你的方法。我不熟悉“setValue”命令。这给了我一些家庭作业要做。