如何在社交媒体应用中阻止 Firebase 上的用户?对于 iOS

Posted

技术标签:

【中文标题】如何在社交媒体应用中阻止 Firebase 上的用户?对于 iOS【英文标题】:How to block users on Firebase in a social media app? for iOS 【发布时间】:2018-10-12 20:50:34 【问题描述】:

enter image description here我的应用已经完成了大约 90%,并准备发布它,以便发布以进行测试。

我被苹果拒绝了,因为我没有一个很重要的功能: - 一种用户阻止滥用用户的机制。

我已经有一个可以关注其他用户的功​​能,但我不知道如何阻止访问,这样当一个用户阻止另一个用户时,他们看不到与刚刚阻止他的用户相关的任何内容.他们无法在搜索、新消息和帖子中看到他们的个人资料。

我不知道从哪里开始。如果您曾经开发过用户内容生成的应用程序。我什至不知道从哪里开始。我已经坚持了 3 周,现在我很绝望。

//我将如何实现这样的东西?

我的安全规则是基本的。


  "rules": 
".read": "auth != null",
".write": "auth != null"

截至目前,我显示信息的方式是,用户必须使用电子邮件、用户名和密码登录,并创建允许他们登录、进入应用程序并查看所有相关内容的用户到应用程序。

我的节点也是如此

Messages

cmets 标记帖子 下列的 喜欢 帖子 用户消息 用户

【问题讨论】:

您介意发布您的安全规则吗?或者,您如何促进向用户显示信息?这将使我们能够更好地了解您的系统如何工作,以帮助您集成阻止功能。 @BryanMassoth 道歉,只是添加了更多细节,抱歉。如果您需要更多信息,请告诉我。 【参考方案1】:

这个问题有很多解决方案。一种方法是在数据库中为被阻止的用户设置一个单独的节点。在每个用户下,您可以列出被屏蔽用户的uid,其值为“true”。值是什么并不重要——这只是让搜索被阻止的人变得更容易。因此,例如,假设这是您的数据库结构:

users:
    uid1:
       my data: 
           // some stuff here
       
    uid2:
       my data: 
           // some stuff here
       
blocked:
     uid1:
         uid8: true,
         uid3: true
     uid2:
         uid1: true

在上面的例子中,uid1 已经屏蔽了uid8uid3,以此类推。 然后,您可以调整您的规则,以验证用户是否可以读取他们是否已通过身份验证并且他们的uid 未在该用户的阻止列表中找到。


  "rules": 
    "users": 
      "$user_id": 
        // only messages from the last ten minutes can be read
        ".read": "auth != null && !root.child('blocked/'+$user_id+'/'+auth.uid+'/true').exists()",
        ".write": "$user_id === auth.uid"
      
    
  

查看有关安全规则的documentation,了解一些安全规则示例。

【讨论】:

我认为我非常接近解决方案。我不确定,为什么当我实施安全规则时,我不断收到“所有用户的 Firebase 访问被拒绝。我的节点与本示例中的相同。 4.12.0 - [Firebase/Database][I-RDB038012] /posts/93WZmGheisepemNsMPKj0RJlYq53 的侦听器失败:permission_denied 而事情是它正在发生在所有用户身上,即使是正在阻止的用户.. 消息被阻止 93WZmGheisepemNsMPKj0RJlYq53 wFsUB1B4d9SvSBKzI0PzzYSXGic2:真正的 cmets 标记的帖子跟随喜欢帖子用户消息用户 我附上了我的数据库结构的屏幕截图。刚开始,我的排名还不允许我上传图片。【参考方案2】:

我假设在您的数据库中某处您有正确的用户模型?只需添加另一个名为 isBlocked 的字段或其他字段,然后根据该值验证某些用户是否可以看到该用户

【讨论】:

我将如何验证它?我已经尝试了上面的解决方案,但是每个用户的访问都被拒绝了 这是因为安全规则适用于数据库中的所有内容,您希望这些规则适用于每个单独的用户 正确的数据库规则是什么?【参考方案3】:

这是我想出的,对我来说效果很好。 这不像 Instagram 那样被屏蔽的用户会从你的信息流中完全消失,但它肯定会让 Apple 陷入困境,因为一个用户可以屏蔽另一个用户,而一旦发生这种情况任何一个都不能互相发送消息。

它还为您提供了在显示操作表时显示“阻止”或“取消阻止”的选项,以便当前用户知道他们是否阻止了其他用户。

首先我假设这是在某种具有发送消息按钮的聊天视图控制器中,并且在该聊天 vc 中有发送者的 id(当前用户)和接收者的 id(其他用户)。

要阻止某人,您可以在 Firebase 中创建 blocked 引用,为想要阻止其他用户的用户创建一个节点,然后最后将被阻止的用户作为键/值对添加到该节点下。 other user's id 即为key,其值为真。

例如。 dog123 想要阻止 cat456。当 dog 决定阻止 cat 时,要阻止的 ref 将是:

let dogId = dog123 // current user
let catId = cat456 // other user

func actionSheetBlockedAction() 

    let dictValues = [String: Any]()
    dictValues.updateValue(true, forKey: catId)

    let ref = Database.database().reference().child("blocked").child(dogId)
    ref.updateChildValues(dictValues)

这将导致数据库看起来像:

root
  |
  @---blocked
         |
         |
         @----dog123
                |
                |----cat456: true  // cat123 is blocked from sending messages to dog123

在同一个聊天 vc 中,您需要添加一些属性,并且在 viewDidLoad 或 viewWillAppear 中,您需要添加 2 个单独的观察者来监听两个用户的阻塞引用。

您必须检查两个用户,因为是 dog123 可能阻止了 cat456,但作为回报 cat456 也可能阻止了 dog123。稍后,如果狗决定解除对猫的阻止,但猫仍然阻止了狗,那么消息仍然会从狗传递给猫。

为了防止您添加观察者,他们会在按下发送按钮时切换您检查的某些属性。如果其中任何一个属性为真,则意味着有人阻止了其他人,并且不应发送任何消息。这些属性会让你知道谁阻止了谁。

您还可以使用这些属性在操作表出现时显示“阻止”或“取消阻止”按钮。

var currentUserId = Auth.auth().currentUser?.uid
var otherUserId = "whatever" // you should already have this
var isCurrentUserBlocked = false
var isOtherUserBlocked = false

override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    checkBlockedRefsForBothUsers() // this is where the isCurrentUserBlocked & isOtherUserBlocked properties get changed



@IBAction func sendMessageButtonTapped(sender: UIButton) 

    if isOtherUserBlocked 
        // alert the current user that they blocked the other user
        return
    

    if isCurrentUserBlocked 
        // alert the current user that the other user blocked them
        return
    

    // if neither are true then let the current user send their message to the other user



func checkBlockedRefsForBothUsers() 

    let currentUsersBlockedRef = Database.database().reference().child("blocked").child(currentUserId!)
    currentUsersBlockedRef?.observe( .value, with:  (snapshot) in

        // if the current user ISN'T under the blocked ref then the other user ISN'T blocked
        if !snapshot.exists() 
            self.isOtherUserBlocked = false
            return
        

        for child in snapshot.children 
            let snap = child as! DataSnapshot

            // if the other user's uid IS under the current user's blocked ref then the other user IS blocked from them
            if snap.key == self.otherUsersId 
                self.isOtherUserBlocked = true
                break
            

             // if the other user's uid ISN'T under the current user's blocked ref then the other user ISN'T blocked
            self.isOtherUserBlocked = false
        
    )

    let otherUsersBlockedRef = Database.database().reference().child("blocked").child(otherUserId)
    otherUsersBlockedRef?.observe( .value, with:  (snapshot) in

        // if the other user's uid ISN'T under the blocked ref then the current user ISN'T blocked
        if !snapshot.exists() 
            self.isCurrentUserBlocked = false
            return
        

        for child in snapshot.children 

            let snap = child as! DataSnapshot

            // if the current user's uid IS under the other user's blocked ref then the current user IS blocked from them
            if snap.key == self.currentUserId 
                self.isCurrentUserBlocked = true
                break
            

             // if the current user's uid ISN'T under the other user's blocked ref then the current user ISN'T blocked
            self.isCurrentUserBlocked = false
        
    )

并在显示操作表时显示“阻止”或“取消阻止”按钮,请使用相同的 2 个属性:

@IBAction func presentActionSheet(sender: UIButton) 

    let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

    let blockAction = UIAlertAction(title: "Block", style: .default)  (action) in
         // run code to block the otherUserId
         self.actionSheetBlockedAction()
    

    let unblockAction = UIAlertAction(title: "Unblock", style: .default)  (action) in
        // run code to unblock the otherUserId
    

    if isOtherUserBlocked 
        actionSheet.addAction(unblockAction) // if the current user blocked the other user then show the "unblock" action
     else 
        actionSheet.addAction(blockAction)  // if the current user didn't block the other user then show the "block" action
    

    present(actionSheet, animated: true, completion: nil)

最后你可能会想,当狗挡住猫时,只更新它们的 refs 是有意义的。这样做的问题是当猫的动作表出现时,使用上面的逻辑会出现猫挡住了狗,而猫的动作表将显示“解锁”。

【讨论】:

以上是关于如何在社交媒体应用中阻止 Firebase 上的用户?对于 iOS的主要内容,如果未能解决你的问题,请参考以下文章

具有社交媒体身份验证的用户的 Firebase 重置密码问题

如何在 iOS 上整合社交媒体进行照片分享?

分享到安装在手机 iOS Swift 上的社交媒体

text 阻止常见的社交媒体

Firebase 托管:检测 facebook、twitter 和 google 等社交媒体爬虫机器人

如何在firebase firestore中准确合并多个流