braze-inc / braze-swift-sdk

Braze SDK for the Apple ecosystem, including: iOS, macOS, iPadOS, visionOS, tvOS
https://www.braze.com
Other
52 stars 19 forks source link

[Bug]: SDK keeps trying to present in app message even after discarding it #84

Closed evelyne96 closed 1 year ago

evelyne96 commented 1 year ago

Platform

iOS

Platform Version

iOS 16.5

Braze SDK Version

7.0.0

Xcode Version

14.3.1

Computer Processor

Apple (M1)

Repro Rate

100%

Steps To Reproduce

Example:

  1. Add braze.logCustomEvent(name: "custom_event") in AppDelegate.swift.
  2. Run the app.

Expected Behavior

New Braze swift SDK to work the same as the Appboy SDK regarding the in-app message presentation. Expected: Once braze delivers the in app message and calls the presentation logic through the delegates it shouldn't try to present the same message again when the displaychoive was discard.

Actual Incorrect Behavior

Trying to update from Appboy to Braze swift sdk and seeing some difference in behaviour for in app message presentation. I have an in app message that should be shown at every session start trigger (with reeligibility enabled, but tested with it disabled as well which still had the same behaviour). With the old SDK once the message was delivered and discarded by returning he correct discard display choice the SDK never tried to present it again. Now after updating to the new one this seems to be different, even after discarding the message the SDK tries to present it again and again until we log an impression on the message. Once the impression is logged the presentation stops being triggered again. Sometimes it also stop after a number of tries.

Is this behaviour expected with the new SDK? Based on the documentation my understanding was that it should be delivered only once even with reeligibility. "By default, Braze sends a message to a user only once, even if they re-qualify." Also note that we are using the default in app message presenter -> BrazeInAppMessageUI

Verbose Logs

No response

Additional Information

No response

jerielng commented 1 year ago

Hi @evelyne96, as long as a user continues to be re-eligible for an in-app message, they will keep receiving it for every time you hit the trigger condition. Our in-app messages are added to a stack every time the trigger is hit, so if it is based on a custom event, you will add N number of in-app message instances to the stack if you call that custom event N times.

Could you clarify what the repeat display behavior you are seeing? When you set an in-app message to discard, it will discard that specific instance of the message, but repeat triggers will add additional instances of that message to the stack for it to be displayed, which may be what you're seeing.

You mentioned that you are setting the message display option to .discard. Are you able to share what your delegate method implementation looks like?

It may also help if you provided a specific campaign that causes this so we can take a deeper look from our end. Would you be able to send a link in to support@braze.com with a reference to this GitHub conversation?

evelyne96 commented 1 year ago

Sure, the trigger is just "session started", so right now it is trying to present the message at every app background/foreground change in this specific case. By discard I mean that the BrazeInAppMessageUIDelegate will return the .discard displayChoice (we have some extra conditional logic to decide which ones to discard)

func inAppMessage(_ ui: BrazeInAppMessageUI,
                      displayChoiceForMessage message: Braze.InAppMessage) -> BrazeInAppMessageUI.DisplayChoice {
   return  condition ? .discard : .now
}

Which I believe is the equivalent to the appboy one regarding the displaychoice: func before(inAppMessageDisplayed inAppMessage: ABKInAppMessage) -> ABKInAppMessageDisplayChoice { }

In my testing the old SDK had a different behaviour and it didn't actully trigger the presentation of the message more than once after it was discarded, even if we did not log an impression on it. So the question is if this change in the behaviour is expected when updating from the old appboy implementation?

jerielng commented 1 year ago

This behavior is expected, and based on some testing, the old SDK should perform the same logic. If your trigger is session start, as long as the user continues to be eligible for that campaign, you should expect to see a fresh instance of the message created on each new session start, even if you returned .discard in the last session.

It's important to note that anytime you background and re-foreground the app, a new session is started, so whenever you re-foreground the app, that session start will trigger the SDK to create a new instance of the in-app message. Whenever you call .discard, you are only discarding that instance of the message, but it does not prevent the trigger from re-occurring and creating a new instance if the conditions are met again (in your case, it would be starting a new session).

If you'd like to control the delivery further, one possible option is playing around with the re-eligibility rules in the IAM dashboard.

evelyne96 commented 1 year ago

I see, so is there any other way to actually discard a message, as in we've received it but don't want to show it to the user or log an impression for it?

jerielng commented 1 year ago

Based on the conditions set up for this campaign, I don't think there's a way this is possible. Discarding a message only removes that instance of it, but since the trigger for this message is session start, every subsequent new session will trigger it again. Disabling re-eligibility on the dashboard also would not be applicable here because in order for a user to no longer be eligible for an IAM, the server must first record an impression for that IAM.

If possible, could you shed some additional insight on the motivation around what you are trying to accomplish? It might help in determining an appropriate approach to handle the incoming message.

evelyne96 commented 1 year ago

We have a very specific use case, where users receive an in app message, but they don't actually see it in certain cases until later on. This includes saving the message in our database as well to show it to the user later, so while they do receive it we don't actually want to log an impression until later on, so receiving it again and again would trigger this processing on our end. We could guard this use case and discard the message afterwards if we already saved it obviously, but since we didn't have this happen with Appboy 4.4.3 (at least not in our dev testing) we wanted to know if there was something we've missed while upgrading or if there was some other way to discard the processed message for good without an impression.

evelyne96 commented 1 year ago

Closed the issue as resolved based on the info that jerielng provided. Thank you for all the clarifications!