如何在社交媒体应用中阻止 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
已经屏蔽了uid8
和uid3
,以此类推。
然后,您可以调整您的规则,以验证用户是否可以读取他们是否已通过身份验证并且他们的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 重置密码问题