stream-chat-swift icon indicating copy to clipboard operation
stream-chat-swift copied to clipboard

Configurable Push Notifications for channel invites

Open SSaleemSSI opened this issue 3 years ago • 12 comments

What did you do?

I have implemented channels for requests with accept and reject states. I do not want to get push notifications if i am invited to that channel through .invite API. Until i accept the request.

What did you expect to happen?

Push notifications wont trigger for users which are invited to channel.

What happened instead?

I received push notifications for all messages if i am invited to channel and wont accept the request.

GetStream Environment

GetStream Chat version: GetStream Chat frameworks: StreamChat, StreamChatUI iOS version: Swift version: Xcode version: Device:

Additional context

I comes up with the new idea to mute the channel upon receiving the notification in notification extension As i have client and channelID both there so i get the channelController and mute the channel but problem comes It give the error "The operation couldn’t be completed. (StreamChat.ClientError.MissingConnectionId error 1.)" I thought that would be the connection problem so as i already have token and userID in extension service of push notification so i connect the client but i also gives error "The operation couldn’t be completed. (StreamChat.ClientError.ClientIsNotInActiveMode error 1.)" So upon study i find that this client is connectionless and cannot be connected. So Either way i need to mute that channel when i received the First notification and as i already changed the content to looks like request. here is the sample code. How can i avoid this error so that i can mute the channel ?

guard let userCredentials = UserDefaults.shared.currentUserToken else {
            
contentHandler(content)
            return
        }
        let apiKeyString = "********"
        let applicationGroupIdentifier = "*******"
        
        var config = ChatClientConfig(apiKey: .init(apiKeyString))
        config.applicationGroupIdentifier = applicationGroupIdentifier

        let client = ChatClient(config: config)
        client.setToken(token: Token(stringLiteral: userCredentials))
        let chatHandler = ChatRemoteNotificationHandler(client: client, content: content)
        
        let chatNotification = chatHandler.handleNotification { chatContent in
            
            
            switch chatContent {
            case let .unknown(messageNotification):
                contentHandler(content)
            case let .message(messageNotification , channelID):
                if messageNotification.channel?.membership != nil{
                    if((messageNotification.channel?.membership?.isInvited == true && messageNotification.channel?.membership?.inviteAcceptedAt == nil && messageNotification.channel?.membership?.inviteRejectedAt == nil)){
                        content.body = "You are invited to "+(messageNotification.channel?.name ?? "Chat room")
                      
                            let muteController = client.channelController(for: channelID)
                            
                            muteController.muteChannel { error in
                                        if let error = error {
                                            // handle error
                                            let error = error.localizedDescription // always gives error 

                                            print(error)
                                        }
                                    }
                                } 
                            }
                        
                       
                        contentHandler(content)
                        return
                    }
                }
                if let activityMembers = messageNotification.message.activityMembers {
                    content.body = self.dynamicActivtyTextParser(activityString: messageNotification.message.text, 
      activtyMembers: activityMembers, channel: messageNotification.channel!)
                    content.subtitle = ""
                    contentHandler(content)
                } else {
                    contentHandler(content)
                }
              // if normal message its throws bug
              
//                }
            default:
                content.title = "default"
                contentHandler(content)
            }
        }

SSaleemSSI avatar Aug 17 '22 07:08 SSaleemSSI

Hi @SSaleemSSI!

Thank you for the report! I will investigate the issue and comeback to you as soon as possible.

Best, Nuno

nuno-vieira avatar Aug 17 '22 16:08 nuno-vieira

Thanks @nuno-vieira Please also make sure that user receive only one request notification if invited to a channel. If user is online either from web/Mobile user also shouldn't receive notifications.

SSaleemSSI avatar Aug 18 '22 08:08 SSaleemSSI

Hi @SSaleemSSI!

On Push Notifications you can only read data, you can't perform POST Requests or Websocket events. So what you are trying to do is not possible. I've talked with the backend team and they will make this feature configurable in the backend so that you can change it to not receive pushes if you didn't accept the invite yet. Unfortunately, right now I don't have an ETA for this, but I'll let you know once this is added.

Best, Nuno

nuno-vieira avatar Aug 19 '22 13:08 nuno-vieira

Hi - @nuno-vieira - We are handling push notifications for requested channels by check in membership of channel that member is invited? if member has accepted/rejected the request. What i am facing the issue is membership of channel is returning nil in notification extension.

case let .message(messageNotification , channelID):
                if messageNotification.channel?.membership != nil{
                    if((messageNotification.channel?.membership?.isInvited == true && messageNotification.channel?.membership?.inviteAcceptedAt == nil && messageNotification.channel?.membership?.inviteRejectedAt == nil)){
                        content.body = "You are invited to "+(messageNotification.channel?.name ?? "Chat room")

here is the sample my code is already explained above. Can u please tell why membership is nil in Notification extension as it was working fine previously.

SSaleemSSI avatar Sep 28 '22 13:09 SSaleemSSI

Hi @SSaleemSSI

Did the user already accept the invite? If not, the membership is nil. Can you debug the network traffic with something like Proxyman, to check the full details of the channel?

nuno-vieira avatar Sep 28 '22 14:09 nuno-vieira

No, i haven't accepted the request but before that without even accepting/rejecting the request, the membership wasn't nil and both the acceptAt and rejectedAt were nil and isInvite was always true, i check the channel by printing the channel its membership was nil. So now how can i check if i am invited to the channel? I tried using lastactivemembers and check user property of isInvited but it also didn't work because ChatClient.shared.currentuserID was nil at that time.

SSaleemSSI avatar Sep 28 '22 18:09 SSaleemSSI

Also i just noticed that membership param isn't nil for channels inside the query, my requested channels are fetching and comparing with the same logic, i haven't accepted the request but still i am getting membership. It's only nil in case if we receive push notification. Screenshot 2022-09-29 at 10 19 28 AM

SSaleemSSI avatar Sep 29 '22 05:09 SSaleemSSI

Hi @SSaleemSSI,

I'm going to check with the backend if something was changed meanwhile. I'll let you know once I have more details.

Best, Nuno

nuno-vieira avatar Sep 29 '22 10:09 nuno-vieira

Btw @SSaleemSSI, what is the SDK version you are using at the moment? And can you confirm, this is not related to updating the SDK right?

nuno-vieira avatar Sep 29 '22 10:09 nuno-vieira

No its not SDK related, we have recently updated, Can it be possible that i am using my custom array as u suggested for pinned channels, and i am removing requested channels from Array as well, when ever push notification triggered it searched for the channel updates in Array of custom array as i am not adding that requested channel so it throws some error?

SSaleemSSI avatar Sep 29 '22 10:09 SSaleemSSI

@nuno-vieira i resolved the issue thanks for looking into the backend, i turned off the local storage in AppCoordinator Configuration due to which channel model data was returning nil values. But still i don't know why turning off local storage has effect on channel payload.

SSaleemSSI avatar Sep 29 '22 11:09 SSaleemSSI

Hi @SSaleemSSI,

I'm not sure what the problem is, especially because you are doing a lot of things that are not a common flow when using Stream.

Either way, great that you were able to fix it.

Best, Nuno

nuno-vieira avatar Sep 29 '22 12:09 nuno-vieira

@nuno-vieira Can u please tell me from where we can config this?

SSaleemSSI avatar Feb 24 '23 12:02 SSaleemSSI