Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] IAM with dynamic trigger showing forever #2137

Merged
merged 3 commits into from
Jul 25, 2024
Merged

Conversation

jinliu9508
Copy link
Contributor

@jinliu9508 jinliu9508 commented Jun 27, 2024

Description

One Line Summary

Fix an issue with IAM with dynamic triggers like "SESSION_TIME" showing up repetitively after being dismissed.

Details

Motivation

Fix the incorrect app behavior when IAM with both custom trigger and session_time trigger continues to show up even it was dismissed.

Scope

  • This issue happens strictly when both a time based trigger like Session_Time and an in-app trigger of "IS NOT EQUAL" exist with AND. The first time both triggers evaluated to true, IAM shows up, gets dismissed, and will reevaluate the triggers again. In the reevaluation, the system first determines if there is only dynamic trigger. If there is, it forces evaluate to false to suppress the IAM from showing up again. But in this case, another in-app trigger exists and will always evaluate to true due to the IS NOT EQUAL characteristics we currently have, thus a repeating IAM occurs.
  • This PR alters the logic on when to redisplay message so that we no longer make redisplay messages available to avoid duplicate redisplay of a same message. A message can be redisplayed if at least one trigger has changed or a new trigger is added when a dynamic trigger exists.

Manual testing

Before the fix:
IAM setting to reproduce the issue:
image
This IAM would show up 5 seconds after app start up and continue to show up after being dismissed.

After the fix:

  1. IAM with whatever IS NOT 5 AND Session_Time > 5 with Every time trigger conditions are satisfied checked:
    • Result: This IAM will show up 5 seconds after app start up and will not show up again once dismissed. Whenever I add a new trigger, the IAM shows up again.
  2. IAM with whatever = true AND Session_Time > 5 with Every time trigger conditions are satisfied checked:
    • Result: This IAM will not show up initially, but will show up if I add a trigger whatever = true EVERY TIME after 5 seconds of startup. If I add a trigger with an unrelated key, the IAM will not show.
  3. IAM with a single trigger whatever2 = 2
    • Result: This IAM will not show up unless a trigger whatever2 = 2 is added. Any value for the same key that is not equals to 2 will not show the IAM.
  4. IAM with a single dynamic trigger Session_Time > 5
    • Result: This IAM will only show once 5 seconds after startup.

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
    • If it is hard to explain how any codes changes are related to each other then it most likely needs to be more than one PR
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
    • Simplify with less code, followed by splitting up code into well named functions and variables, followed by adding comments to the code.
  • I have reviewed this PR myself, ensuring it meets each checklist item
    • WIP (Work In Progress) is ok, but explain what is still in progress and what you would like feedback on. Start the PR title with "WIP" to indicate this.

This change is Reviewable

@jinliu9508 jinliu9508 changed the title WIP: [FIX] IAM with dynamic trigger does not show forever [FIX] IAM with dynamic trigger does not show forever Jun 27, 2024
@jinliu9508 jinliu9508 force-pushed the IAM-display-forever branch 2 times, most recently from ba52ee5 to 49be2fc Compare July 1, 2024 17:52
@jinliu9508 jinliu9508 changed the title [FIX] IAM with dynamic trigger does not show forever [FIX] IAM with dynamic trigger showing forever Jul 1, 2024
@jinliu9508 jinliu9508 requested a review from jkasten2 July 1, 2024 18:01
@jinliu9508 jinliu9508 force-pushed the IAM-display-forever branch 2 times, most recently from 30dc970 to a3bc16c Compare July 2, 2024 19:55
@jinliu9508 jinliu9508 requested a review from jkasten2 July 2, 2024 19:58
Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This latest solution still looks like it would also break the "Every time trigger conditions are satisfied" behavior. We want to keep the behavior where the developer should be able to reshow the IAM by calling addTrigger again with the same key. Can you test this scenario and add what you tested to the PR notes?

@jinliu9508
Copy link
Contributor Author

This latest solution still looks like it would also break the "Every time trigger conditions are satisfied" behavior. We want to keep the behavior where the developer should be able to reshow the IAM by calling addTrigger again with the same key. Can you test this scenario and add what you tested to the PR notes?

The latest change adds a set that stores evaluated combinations of trigger to prevent a certain combination of trigger from showing multiple time. The set will get cleared every time addTrigger or removeTrigger is called. And it appears in my test that the IAM will show up once per startup and every time I add a new trigger.

Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new logic has a lot of overlap with the pre-existing isTriggerChanged and isDisplayedInSession logic. I think we should remove these (if they cover everything) before merging in these changes so we don't have redundant logic that would much harder to reason about later.

Summary of changes:
  1. When a time-based trigger is evaluated and 'onTriggerCompleted()' is called, we no longer make redisplay messages available to avoid duplicate redisplay of a same message.
  2. Modify the logic of 'makeRedisplayMessagesAvailableWithTriggers()' so that a message can be redisplayed only if at least one trigger has changed or a new trigger is added.
  3. 'onTriggerConditionChanged()' now accepts a new parameter 'triggerId' that indicates the time-based trigger that fires.
@jinliu9508
Copy link
Contributor Author

This new logic has a lot of overlap with the pre-existing isTriggerChanged and isDisplayedInSession logic. I think we should remove these (if they cover everything) before merging in these changes so we don't have redundant logic that would much harder to reason about later.

Yes, I also realized that this particular approach uses similar logic as 'isTriggerChanged' so I made a different approach that only alter the 'makeRedisplayMessagesAvailableWithTriggers' logic so that onTriggerCompleted no longer redisplay messages. Instead, it was done by onTriggerConditionChanged before trigger evaluation. I have updated the test part in the description to include some common IAM setup that is potentially affected by the change.

@jinliu9508 jinliu9508 requested a review from jkasten2 July 18, 2024 06:27
Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. IAM with whatever = true AND Session_Time > 5 with Every time trigger conditions are satisfied checked:

There is still a bug with that IAM in the follow scenario.

  1. Call addTriger("whatever", true)
  2. IAM displays as expected
  3. Call addTriger("somethingElse", true)
  4. BUG: IAM displays again when it should not
    • It is expected that it only re-display if addTriger("whatever", true) was called again.

…r is added when there is only dynamic trigger
@jinliu9508
Copy link
Contributor Author

  1. IAM with whatever = true AND Session_Time > 5 with Every time trigger conditions are satisfied checked:

There is still a bug with that IAM in the follow scenario.

  1. Call addTriger("whatever", true)

  2. IAM displays as expected

  3. Call addTriger("somethingElse", true)

  4. BUG: IAM displays again when it should not

    • It is expected that it only re-display if addTriger("whatever", true) was called again.

Nice found! I have fixed this bug and removed some unneeded code for the latest commit.

@jinliu9508 jinliu9508 requested a review from jkasten2 July 24, 2024 14:38
Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No action needed in this PR, but noted here for the future. I think there is still more states the can be cleaned up to simplify this manager's logic. Some that come to mind are:

  1. I don't think messageHasOnlyDynamicTriggers needs to be a concept
  2. redisplayedInAppMessages overlaps with message.isDisplayedInSession

if (!message.isTriggerChanged && redisplayedInAppMessages.contains(message) &&
_triggerController.isTriggerOnMessage(message, newTriggersKeys)
) {
val isMessageDisplayed = redisplayedInAppMessages.contains(message)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isMessageDisplayed is an incorrect name for this, however the pre-existing redisplayedInAppMessages is also a misleading name. A recommend a better name such as canRedisplay instead of isMessageDisplayed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I just fixed this.

val isMessageDisplayed = redisplayedInAppMessages.contains(message)
val isTriggerOnMessage = _triggerController.isTriggerOnMessage(message, newTriggersKeys)
val isOnlyDynamicTriggers = _triggerController.messageHasOnlyDynamicTriggers(message)
if (!message.isTriggerChanged && isMessageDisplayed && (isTriggerOnMessage || isNewTriggerAdded && isOnlyDynamicTriggers)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is acceptable for now, however keep in mind for the future ideally we won't want to have an if statement with a nested && and || like this in most scenarios, including this one.

@jinliu9508 jinliu9508 merged commit cb37657 into main Jul 25, 2024
2 of 3 checks passed
@jinliu9508 jinliu9508 deleted the IAM-display-forever branch July 25, 2024 15:40
@jinliu9508 jinliu9508 mentioned this pull request Jul 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants