首页 > 解决方案 > 如何在没有用户身份验证的情况下使用 Firebase 实现投票系统?

问题描述

我正在构建一个应用程序,其中将使用 firebase 实现支持系统,但该应用程序没有用户 logi0/signup,我也不希望添加一个。我已经阅读了有关如何在我的应用程序中实现支持系统的文档transaction() ,但我不知道如何在没有用户登录的情况下使用它?我有一个类似于 Firebase 文档中给出的 Post 类

public class _Post {
public String uid;
public String timeStamp;
public String author;
public String body;
public int starCount = 0;
public Map<String, Boolean> stars = new HashMap<>();

public _Post() {
    // Default constructor required for calls to DataSnapshot.getValue(Post.class)
}

public _Post(String uid, String author, String body, String timeStamp) {
    this.uid = uid;
    this.author = author;
    this.body = body;
    this.timeStamp = timeStamp;
}

@Exclude
public Map<String, Object> toMap() {
    HashMap<String, Object> result = new HashMap<>();
    result.put("uid", uid);
    result.put("author", author);
    result.put("body", body);
    result.put("starCount", starCount);
    result.put("stars", stars);
    result.put("time", timeStamp);
    return result;
}

public String getUid() {
    return uid;
}

public String getTimeStamp() {
    return timeStamp;
}

public String getAuthor() {
    return author;
}

public String getBody() {
    return body;
}

public int getStarCount() {
    return starCount;
}

public Map<String, Boolean> getStars() {
    return stars;
}

}

这是我的投票方法,我也从firebase docs/guide中获得

private void onStarClicked(String postId, final String uid) {
    DatabaseReference postRef = mDatabaseRef.child("north_america").child("posts").child(postId);
    postRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            _Post p = mutableData.getValue(_Post.class);
            if (p == null) {
                return Transaction.success(mutableData);
            }

            if (p.stars.containsKey(uid)) {
                // Unstar the post and remove self from stars
                p.starCount = p.starCount - 1;
                p.stars.remove(uid);
            } else {
                // Star the post and add self to stars
                p.starCount = p.starCount + 1;
                p.stars.put(uid, true);
            }

            // Set value and report transaction success
            mutableData.setValue(p);
            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b,
                               DataSnapshot dataSnapshot) {
            // Transaction completed
            Log.d(TAG, "postTransaction:onComplete:" + databaseError);
        }
    });
}

我遇到的另一个问题是我的 firebase Posts 节点会是什么样子?也许像这样?(我的应用谈论即将上映的电影)

-- north_america
--- posts
---- movie_id

movie_id会是这样吗?

在这个例子中,1123 是电影的 id

"1123": {
    "uid": "user_2",
    "title": "I am legend"
    "likes": 0
}

Posts 节点中的 Post 对象将包含什么?

标签: androidfirebasefirebase-realtime-database

解决方案


如果您希望在不要求用户提供凭据的情况下安全地识别设备/会话,则可以使用Firebase 的匿名身份验证。这允许您通过简单地调用为当前设备上的用户创建一个“会话”:

FirebaseAuth.getInstance().signInAnonymously()

这可以识别客户端上和(更重要的是)服务器上的用户,这样您就可以确保每个用户只能投票一次。

如果您不关心限制每个用户的投票数,而只是想以likes事务方式增加电影的投票数,请在每次点击时执行以下操作:

private void onStarClicked(String postId, final String uid) {
    DatabaseReference postRef = mDatabaseRef.child("north_america/posts").child(postId).child("likes");
    postRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Long value = mutableData.getValue(Long.class);
            if (value == null) value = new Long(0);
            mutableData.setValue(value + 1);
            return Transaction.success(mutableData);

        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b,
                               DataSnapshot dataSnapshot) {
            // Transaction completed
            Log.d(TAG, "postTransaction:onComplete:" + databaseError);
        }
    });
}

代码只是在属性上执行一个事务likes,增加它的值。


推荐阅读