How to block users on Firebase in a social media app? for iOS

主宰稳场 提交于 2021-02-18 03:41:51

问题


enter image description hereI'm about 90% with my app, and was ready to release it so it can be released to get tested.

I was rejected by apple, because i didn't have a very important feature: - A mechanism for users to block abusive users.

I already have a function in which I follow other users, but I'm stuck on how do I block access, so that when one users blocks the other, they don't see anything related to the one who just blocked him. They can't see their profile in search, in new messages, and their posts.

i don't know where to begin. If you've worked on a user-content generated app. I don't even know where to begin. I've been stuck on this for 3 weeks and now I'm desperate.

//how would I implement something like this?

my security rules are basic.

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

} }

the way i display information, as of right now, is that users have to log in with just an email and username and password using and that creates' and user that allows them to log in, into the app and see everything related to the app.

my nodes as well

Messages

comments flagged-posts following likes posts user-messages users


回答1:


There are lots of solutions to this problem. One way is to have a separate node in the database for blocked users. Under each user, you can list the uid of the blocked user with a value of "true". Doesn't really matter what the value is--this just makes it easier to search for who is blocked. So, for example, say this is your database structure:

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

In the above example, uid1 has blocked uid8 and uid3, and so on. Then you can align your rules to verify that the user can read if they are authenticated and their uid isn't found on that user's blocked list.

{
  "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"
      }
    }
  }
}

Check out the documentation on security rules for some examples of security rules.




回答2:


I asume somewhere in your DB you have a User Model correct? simply add another field called isBlocked or whatever and according to that value you'd validate if certain users can see that user or not




回答3:


This is what I came up with and it works fine for me. It isn't like instagram where the blocked user completely disappears from your feed but it will definitely keep Apple at bay because one user can block another user and once that happens neither can send a message to one another.

It also gives you the option to show a "block" or "unblock" when the action sheet is presented so that way the current user knows wether they did or didn't block the other user.

First thing is I'm assuming this is inside some sort of chat view controller that has a send message button and inside that chat vc there is the sender's id (current user) and the receiver's id (other user).

To block someone you create a blocked ref in Firebase, create a node for the user who wants to block the other user and then finally add the blocked user as a key/value pair under that node. The other user's id is the key and the value can be true.

For eg. dog123 wants to block cat456. When the dog decides to block the cat the ref to block at would be would be:

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)
}

This would result in the database looking like:

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

Inside the same chat vc you need to add some properties and in viewDidLoad or viewWillAppear you need to add 2 separate observers to listen to the blocked ref for both users.

You have to run a check on both user's because yeah dog123 might have blocked cat456 but in return cat456 might also have blocked dog123. Later on if the dog decides to unblock the cat but the cat still has the dog blocked then messages will still get through from the dog to the cat.

To prevent that you add the observers and they'll toggle on some properties that you check when the send button is pressed. If either of the properties are true that means somebody blocked somebody else and no messages should get sent. The properties will let you know who blocked who.

You can also use those properties to show the "block" or "unblock" button when the action sheet appears.

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
        }
    })
}

And to show a "block" or "unblock" button when the action sheet is presented use those same 2 properties:

@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)
}

Finally you might think to yourself that when the dog blocked the cat it would make sense to just update the refs for both of them. The problem with that is when the cat's action sheet is presented, using the logic above it will appear that the cat blocked the dog and the cat's action sheet will show "unblock".



来源:https://stackoverflow.com/questions/50139809/how-to-block-users-on-firebase-in-a-social-media-app-for-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!