交易未更新android firestore中的属性

时间:2018-08-31 12:35:38

标签: android google-cloud-firestore

我正在尝试在帖子中添加喜欢或不喜欢的功能(问题)。但这不是更新“赞”按钮图像。

public class QuestionDetailActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "QuestionDetailActivity";
    private Context mContext;
    private TextView questionTitleTv;
    private RadioGroup radioLL;
    private EditText answerEt;
    private LinearLayout checkboxLL;
    private LinearLayout commentLL;

    private FirebaseFirestore db = null;
    private String questionID;

    private String userID;
    private TextView likeCountTv,favouriteCountTv;
    private boolean isLikedByUser = false,isFavouriteByUser = false;
    private DocumentReference questionRef;
    private QuestionBO questionBO;

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

        mContext = QuestionDetailActivity.this;
        db = FirebaseFirestore.getInstance();

        userID = "V5BUeBFYR8WKOQUiBFxKrfMHK8Y2";

        questionTitleTv = findViewById(R.id.tv_question_title);
        radioLL = findViewById(R.id.ll_radio);
        answerEt = findViewById(R.id.et_answer);
        checkboxLL = findViewById(R.id.ll_checkbox);
        commentLL = findViewById(R.id.ll_comments);

        likeCountTv = findViewById(R.id.tv_like_count);
        favouriteCountTv = findViewById(R.id.tv_favourite_count);

        likeCountTv.setOnClickListener(this);
        favouriteCountTv.setOnClickListener(this);

        if (getIntent() != null) {
            questionID = getIntent().getExtras().getString("keyQuestionID", "");
        }
        questionRef = db.collection("questionCollection").document(questionID);
        if (!questionID.isEmpty()) {
            getQuestionDetail();
            ///showComments();
            updateFavouriteAndLikeIcons();
        }
    }

    private void updateFavouriteAndLikeIcons() {

        questionRef.collection("favouriteCollection").document(userID).get()
                .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                    @Override
                    public void onSuccess(DocumentSnapshot documentSnapshot) {
                        if(documentSnapshot.exists()){
                            isFavouriteByUser = true;
                            // and make it blue
                            Drawable image = getResources().getDrawable( R.drawable.icn_fav_yes );
                            int h = image.getIntrinsicHeight();
                            int w = image.getIntrinsicWidth();
                            image.setBounds( 0, 0, w, h );
                            favouriteCountTv.setCompoundDrawables( image, null, null, null );
                        }
                    }
                });

        questionRef.collection("likeCollection").document(userID).get()
                .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                    @Override
                    public void onSuccess(DocumentSnapshot documentSnapshot) {
                        if(documentSnapshot.exists()){
                            boolean isLiked = documentSnapshot.getBoolean(userID);
                            if(isLiked){
                                isLikedByUser = true;
                                // and make it blue
                                Drawable image = getResources().getDrawable( R.drawable.icn_like_yes );
                                int h = image.getIntrinsicHeight();
                                int w = image.getIntrinsicWidth();
                                image.setBounds( 0, 0, w, h );
                                likeCountTv.setCompoundDrawables( image, null, null, null );
                            }
                            else{//dislike
                            }
                        }
                    }
                });

    }

    private void showComments() {
        db.collection("commentCollection").whereEqualTo("questionID", questionID)
                .get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        if (queryDocumentSnapshots.isEmpty()) {
                            Log.d(TAG, "onSuccess: LIST EMPTY");
                            return;
                        } else {
                            // Convert the whole Query Snapshot to a list
                            // of objects directly! No need to fetch each
                            // document.
                            List<CommentBO> commentList = queryDocumentSnapshots.toObjects(CommentBO.class);

                            if (commentList != null && commentList.size() > 0) {
                                for (int x = 0; x < commentList.size(); x++) {
                                    try {
                                        LinearLayout.LayoutParams childParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                                                LinearLayout.LayoutParams.WRAP_CONTENT);

                                        childParam.setMargins(20, 10, 0, 0);
                                        View commentByView = LayoutInflater.from(mContext).inflate(R.layout.item_comment, null);
                                        TextView tvCommenter = (TextView) commentByView.findViewById(R.id.item_tv_commenter_name);
                                        TextView tvCommenterComment = (TextView) commentByView.findViewById(R.id.item_tv_commenter_comment);
                                        TextView tvCommentDate = (TextView) commentByView.findViewById(R.id.item_tv_comment_date);

                                        tvCommenter.setText(commentList.get(x).getCommentedBy());
                                        tvCommenterComment.setText(commentList.get(x).getComment());

                                        ///tvCommentDate.setText();
                                        commentLL.addView(commentByView, childParam);

                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                });
    }

    private void getQuestionDetail() {
        questionRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        Log.d(TAG, "DocumentSnapshot data: " + document.getData());
                        questionBO = document.toObject(QuestionBO.class);
                        updateView(questionBO);
                    } else {
                        Log.d(TAG, "No such document");
                    }
                } else {
                    Log.d(TAG, "get failed with ", task.getException());
                }
            }
        });
    }

    private void updateView(QuestionBO mQuestionBO) {
        if (mQuestionBO != null) {
            questionTitleTv.setText(mQuestionBO.getTitle());

            likeCountTv.setText(mQuestionBO.getTotalLikes() + "");
            favouriteCountTv.setText(mQuestionBO.getTotalFavourites() + "");

            switch (mQuestionBO.getQuestionType()) {
                case CHECKBOX:
                    checkboxLL.setVisibility(View.VISIBLE);
                    if (mQuestionBO.getOptions() != null && mQuestionBO.getOptions().size() > 0) {
                        checkboxLL.removeAllViews();

                        for (int x = 0; x < mQuestionBO.getOptions().size(); x++) {
                            final CheckBox subCheckbox = new CheckBox(mContext);
                            subCheckbox.setText(mQuestionBO.getOptions().get(x));
                            subCheckbox.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {

                                }
                            });

                            checkboxLL.addView(subCheckbox, new LinearLayout.LayoutParams(
                                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                        }
                    }
                    break;
                case RADIO:
                    radioLL.setVisibility(View.VISIBLE);
                    if (mQuestionBO.getOptions() != null && mQuestionBO.getOptions().size() > 0) {
                        radioLL.removeAllViews();

                        for (int x = 0; x < mQuestionBO.getOptions().size(); x++) {

                            final RadioButton subRadio = new RadioButton(mContext);
                            subRadio.setText(mQuestionBO.getOptions().get(x));
                            radioLL.addView(subRadio, new LinearLayout.LayoutParams(
                                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                        }
                    }
                    break;
                case DESCRIPTIVE:
                    answerEt.setVisibility(View.VISIBLE);
                    break;
            }
        }
    }

    private void likeOrDislikeThisQuestion(){

        final Task<Boolean> booleanTask = db.runTransaction(new Transaction.Function<Boolean>() {

            @Nullable
            @Override
            public Boolean apply(@NonNull Transaction transaction) throws FirebaseFirestoreException {
                DocumentReference likeRef = questionRef.collection("likeCollection")
                        .document(userID);
                Map<String,Object> map = new HashMap<>();
                 DocumentSnapshot snapshot = transaction.get(likeRef);
                 if(snapshot.exists()){ // it means this is a favourite question of this user.
                     if(snapshot.getBoolean(questionID) && isLikedByUser){
                         isLikedByUser = false;
                         map.put(questionID,isLikedByUser);
                         transaction.update(likeRef,map);
                         int numberOfLikes = questionBO.getTotalLikes();
                         transaction.update(questionRef,"totalLikes",--numberOfLikes);
                         likeCountTv.setText(numberOfLikes + "");
                         return isLikedByUser;
                     }
                     else if(!snapshot.getBoolean(questionID) && !isLikedByUser){
                         isLikedByUser = true;
                         map.put(questionID,isLikedByUser);
                         transaction.update(likeRef,map);
                         int numberOfLikes = questionBO.getTotalLikes();
                         transaction.update(questionRef,"totalLikes",-++numberOfLikes);
                         likeCountTv.setText(numberOfLikes + "");
                         return isLikedByUser;
                     }
                 }
                 else {
                     isLikedByUser = !isLikedByUser;
                     map.put(questionID,isLikedByUser);// pass oposite of it..
                     transaction.set(likeRef,map);

                     int numberOfLikes = questionBO.getTotalLikes();
                     if(isLikedByUser)
                         ++numberOfLikes;
                     else
                         --numberOfLikes;
                     transaction.update(questionRef,"totalLikes",numberOfLikes);

                     likeCountTv.setText(numberOfLikes + "");
                     return isLikedByUser;
                 }
                return null;
            }
        });

        booleanTask.addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isLiked) {
                if(isLiked == null){

                }
                else if(isLiked){
                    Drawable image = getResources().getDrawable( R.drawable.icn_like_yes );
                    int h = image.getIntrinsicHeight();
                    int w = image.getIntrinsicWidth();
                    image.setBounds( 0, 0, w, h );
                    likeCountTv.setCompoundDrawables( image, null, null, null );
                }
                else{
                    Drawable image = getResources().getDrawable( R.drawable.icn_like_no );
                    int h = image.getIntrinsicHeight();
                    int w = image.getIntrinsicWidth();
                    image.setBounds( 0, 0, w, h );
                    likeCountTv.setCompoundDrawables( image, null, null, null );
                }
            }
        });
    }

    private void favouriteOrDisFavouriteQuestion(){

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.tv_like_count:
                likeOrDislikeThisQuestion();
                break;
            case R.id.tv_favourite_count:
                break;
        }
    }
}

我第一次使用updateFavouriteAndLikeIcons()更新了图标。然后,当用户单击类似按钮时,我叫likeOrDislikeThisQuestion()。计数器正在更新,但可绘制状态未更新。有时变量isLikedByUser变为false。

如果问题已经被喜欢,那么likeCollection必须具有该Document。如果该文档不存在,则表示用户不喜欢或不喜欢它。

我的数据库架构就像

 - likeCollection
      userID (Document ID)
         questionID = true // true for like and false for dislike..

1 个答案:

答案 0 :(得分:1)

来自Firebase docs

  

请勿在事务功能内部修改应用程序状态。这样做会引入并发问题,因为事务功能可以运行多次,并且不能保证在UI线程上运行。而是从事务功能中传递所需的信息。

这就是这里发生的情况,您必须在变量booleanTask的侦听器中运行每个应用程序修改。不要在事务的apply方法中更改类变量。