【问题标题】:How to allow each user rate once time only in Firebase rating system如何在 Firebase 评分系统中只允许每个用户评分一次
【发布时间】:2018-03-30 10:44:11
【问题描述】:

以下是我的 Android 应用程序中每条徒步路线的评分系统。用户可以对每条路径进行评分并实时显示平均评分。但现在的问题是每个用户可以为每条路径多次评分。我想让用户只对每条路径进行一次评分。我是否需要更改 Firebase 数据结构,或者我可以按如下方式重写代码以实现这一点?谢谢:)

public class XXXAcitvity extends AppCompatActivity implements RatingDialogListener {

public String trailId="";
public FloatingActionButton rateButton;
public RatingBar ratingBar;

FirebaseDatabase mDatabase;
DatabaseReference trails;
DatabaseReference ratings;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.XXX);

    Intent intent = this.getIntent();
    rateButton=(FloatingActionButton)findViewById(R.id.ratingbtn) ;
    ratingBar=(RatingBar)findViewById(R.id.ratingbar);

    //Firebase
    mDatabase= FirebaseDatabase.getInstance();
    trails = mDatabase.getReference("Trails");
    ratings = mDatabase.getReference("Ratings");

    //get intent

    if(getIntent()!=null)
    {
        trailId=getIntent().getStringExtra("TrailID");

    }

    if(!trailId.isEmpty())
    {

        getRatingTrail(trailId);

    }

点击评分按钮时,firebase会自动为每个评分生成随机key,并根据评分类模型设置值,trailId是Firebase中同时指向Ratings child和Trails child的key

    @Override
public void onPositiveButtonClicked(int value, String comment) {
    //
     final Rating rating = new Rating(FirebaseAuth.getInstance().getCurrentUser().getUid(),
             trailId,
            String.valueOf(value),
            comment);

     ratings.push().setValue(rating)
             .addOnCompleteListener(new OnCompleteListener<Void>() {
                 @Override
                 public void onComplete(@NonNull Task<Void> task) {

                 }
             });

@Override
public void onNegativeButtonClicked() {

}
}

这是在firebase中计算平均评分的函数

private void getRatingTrail(String trailId)
{
    Query trailRating = 
 ratings.orderByChild("trailId").equalTo(trailId);


    trailRating.addValueEventListener(new ValueEventListener() {
       int count=0;
       int sum=0;
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot postSnapshot:dataSnapshot.getChildren())
            {

                Rating item = postSnapshot.getValue(Rating.class);
                sum+=Integer.parseInt(item.getRateValue());
                count++;

            }

            if(count!=0)
            {
                int average= sum/count;
                ratingBar.setRating(average);
            }




        }

评级等级

public class Rating {
  private String UserID;
  private String trailId;
  private String rateValue;
  private String comment;

  public Rating(){

  }

public Rating(String UserID, String trailId, String rateValue, String comment) {
    this.UserID = UserID;
    this.trailId = trailId;
    this.rateValue = rateValue;
    this.comment = comment;
}

public void setUserID(String UserID) {
    UserID = UserID;
}

public void setTrailId(String trailId) {
    trailId = trailId;
}

public void rateValue(String rateVaule) {
    this.rateValue = rateVaule;
}

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

public String getUserID() {
    return UserID;
}

public String getTrailId() {
    return trailId;
}

public String getRateValue() {
    return rateValue;
}

public String getComment() {
    return comment;
}

}

这是我的数据库结构

"Ratings" : {
"-L8qMG4cttR7VIYMrhNS" : {
  "comment" : "",
  "rateValue" : "1",
  "trailId" : "Trail1",
  "userID" : "bNgsbQKk7rcb755ISW6oDo7EUaJ3"
},
"-L8qMLRyC5TV2kULIMm2" : {
  "comment" : "",
  "rateValue" : "1",
  "trailId" : "Trail2",
  "userID" : "bNgsbQKk7rcb755ISW6oDo7EUaJ3"
},
"-L8qMOdE1QylSX8smLb7" : {
  "comment" : "",
  "rateValue" : "5",
  "trailId" : "Trail2",
  "userID" : "bNgsbQKk7rcb755ISW6oDo7EUaJ3"
},
"-L8qMQjjTCqqCBJ5dbFe" : {
  "comment" : "",
  "rateValue" : "5",
  "trailId" : "Trail2",
  "userID" : "bNgsbQKk7rcb755ISW6oDo7EUaJ3"
},

"-L8qN3RZTPWXy3cWSf2h" : {
  "comment" : "",
  "rateValue" : "1",
  "trailId" : "Trail2",
  "userID" : "oWrUNCA7P8QJlzG1sZ6sHwEcBfu1"
},
"-L8qN8LNzIZNMwu0EGwE" : {
  "comment" : "",
  "rateValue" : "5",
  "trailId" : "Trail2",
  "userID" : "oWrUNCA7P8QJlzG1sZ6sHwEcBfu1"
},
"-L8qNEWQ7GSFPpxJMA9A" : {
  "comment" : "",
  "rateValue" : "5",
  "trailId" : "Trail3",
  "userID" : "oWrUNCA7P8QJlzG1sZ6sHwEcBfu1"
},
"-L8qNP_e45GaJj4EnmKV" : {
  "comment" : "",
  "rateValue" : "1",
  "trailId" : "Trail3",
  "userID" : "kK2ERTyxUgRo4cvrG8gOsN8tRge2"
},
"-L8qNUtkWJjqHlVkFOZy" : {
  "comment" : "",
  "rateValue" : "1",
  "trailId" : "Trail3",
  "userID" : "kK2ERTyxUgRo4cvrG8gOsN8tRge2"
}

},

"Trails" : {
  "Trail1" : {
  "TimeDuration" : "60mins",
  "dec" : "the most pretty trails",
  "distance" : "20km",
  "name" : "Dragon Backs",
  "trailId" : "Trail1"
},
"Trail2" : {
  "name" : "Hike 2",
  "trailId" : "Trail2"
},
"Trail3" : {
  "name" : "Hike 3",
  "trailId" : "Trail3"
}

},

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    要实现这一点,您必须检查用户是否已经对 Trail 进行了评分,使用您的数据库结构,您必须检查所有 Rating 表,并查看 userId 和他投票的 trail 的名称是否在名单。然而,这是非常低效的。

    我的建议是创建一个新表 users-trails,您可以在其中存储用户评分的所有路径。

    例如对于用户:bNgsbQKk7rcb755ISW6oDo7EUaJ3

    "users-trails" : {
     "-bNgsbQKk7rcb755ISW6oDo7EUaJ3" : {
       Trail1: 1
       Trail2: 1
    },
    

    那么当您想查看用户是否已经对 Trail1 进行了评分时,您只需在此表中快速检查一下即可。

    将数据添加到此表的代码很简单:

    FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
    DatabaseReference userTrailsDB = mDatabase.getReference("user-trails");
    
    userTrailsDB.child(userID).child(trailId).setValue(1);
    

    而且要获取信息,也不是很复杂:

    userTrailsDB.child(userID).child(trialId).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                   //Do Whatever if exits
                } 
    
    
                @Override
                public void onCancelled(DatabaseError error) {
    
                }
            };
    

    【讨论】:

    • 我应该把userTrailsDB.child(userID).child(trailId).setValue(1);放在哪里,因为在将值设置到这个userTrailsDB之前,我还需要检查用户是否对路径进行评分
    • 您应该在将某些内容添加到表评级时调用它。因此,每次您向表 rating 中添加一个值时,也要向该表中添加一个值。
    猜你喜欢
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-11
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多