OneSignal / OneSignal-iOS-SDK

OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your native iOS app with OneSignal. https://onesignal.com
Other
496 stars 263 forks source link

[Bug] Fix processing of Identify User response if the user has changed since then #1427

Closed nan-li closed 6 months ago

nan-li commented 6 months ago

Description

One Line Summary

Fix processing of Identify User response when the user has changed since, so that pending updates will still be sent and transfer subscription happens only in correct situations.

Details

Note that this bug only manifests if multiple logins to different users are called one after another, or the requests are not able to succeed (server is down, or there is no internet connection during which time multiple logins are called). This PR tests and addresses those scenarios.

Motivation

Consider the scenario Anon -> Login User A (Identify User) -> Login User B (Create User)

This PR also fixes the bugs mentioned under Manual Testing section for https://github.com/OneSignal/OneSignal-iOS-SDK/pull/1418

User State Change Observer

⚠️ The User Observer was never triggered for the 409'd middle user. That is still the case after this PR, as we never hydrate its onesignal_id.

Scope

Testing

Unit testing

Manual testing

Tested on iPhone 13 with iOS 17.4

✅ Scenario 1:

  1. On new app install after initialization, immediately call these methods.
  2. Confirm tags are sent to <some_existing_euid> by way of external_id
    
    // New App Install

[OneSignal initialize: withLaunchOptions:launchOptions];

[OneSignal login:]; // returns 409 [OneSignal.User addTagWithKey:@"a" value:@"a"]; [OneSignal login:];


### ✅ Scenario 2:

1. On **new app install** after initialization, immediately call these methods.
2. Confirm every update is sent and is sent to the correct user.
```objc
// New App Install

[OneSignal initialize:<app_id> withLaunchOptions:launchOptions];

[OneSignal.User addTagWithKey:@"a" value:@"a"];
[OneSignal.User setLanguage:@"fr"];
[OneSignal.User addAliasWithLabel:@"a" id:@"a"];
[OneSignal.User addEmail:@"a@example.com"];

[OneSignal login:<some_existing_euid>];
[OneSignal.User addAliasWithLabel:@"existing" id:@"existing"];
[OneSignal.User addTagWithKey:@"existing" value:@"existing"];
[OneSignal.User setLanguage:@"zh"];
[OneSignal.User addEmail:@"existing@example.com"];

[OneSignal logout];
[OneSignal.User addTagWithKey:@"c" value:@"c"];
[OneSignal.User setLanguage:@"es"];
[OneSignal.User addEmail:@"c@example.com"];
[OneSignal.User addAliasWithLabel:@"anonymous" id:@"anonymous"];

✅ Scenario 3:

  1. Check everything is correct when the current user is still the same as the Identified User (no regression).
  2. On new app install after initialization, immediately call these methods.
  3. Confirm every update is sent and is sent to the correct user.
  4. The user in the SDK is correctly hydrated.
    
    // New App Install

[OneSignal initialize: withLaunchOptions:launchOptions];

[OneSignal.User addTagWithKey:@"a" value:@"a"]; [OneSignal.User setLanguage:@"fr"]; [OneSignal.User addAliasWithLabel:@"a" id:@"a"]; [OneSignal.User addEmail:@"a@example.com"];

[OneSignal login:]; [OneSignal.User addAliasWithLabel:@"existing" id:@"existing"]; [OneSignal.User addTagWithKey:@"existing" value:@"existing"]; [OneSignal.User setLanguage:@"zh"]; [OneSignal.User addEmail:@"existing@example.com"];

// Don't logout or login to another user


### ✅ Scenario 4:
1. Turn off wifi and data (**no network connection**)
2. New app install and call the following methods
```objc
// New App Install

[OneSignal initialize:<app_id> withLaunchOptions:launchOptions];
[OneSignal login:<some_existing_euid>];
[OneSignal.User addTagWithKey:@"a" value:@"a"];
[OneSignal login:<user_b>];

// No requests go through
  1. Wait 30 seconds and kill app
  2. Turn on wifi and reopen app
  3. Requests go to the correct users.

Affected code checklist

Checklist

Overview

Testing

Final pass


This change is Reviewable

nan-li commented 6 months ago

Followup PR https://github.com/OneSignal/OneSignal-iOS-SDK/pull/1430 testing user switching is also testing these changes.

Note CodeQL is broken after push to start live activities merged to main, its autobuild action no longer works.