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

Branch.setUseTestBranchKey(true) is ignored during initialization and all events reported into LIVE environment if Branch.getInstance() called before the initialization #1370

Open
vitalii-tym opened this issue Mar 27, 2024 · 4 comments

Comments

@vitalii-tym
Copy link

Describe the bug

I have two keys - "test" and "live" in the .plist file:

Screenshot 2024-03-27 at 17 56 06

The SDK is asked to use one of the keys depending on the build being created: everything built for debugging or testing has either DEV or STAGE in Active Compilation Conditions in Build Settings. There can be no mistake, because the same #if ... #endif is used to choose between Dev, Stage, and Prod servers.

My initialization code is:

private func initializeBranch(adsPesonalizationConsent: Bool) {
        #if DEV || STAGE
        Branch.setUseTestBranchKey(true)
        Branch.getInstance().enableLogging(at: .warning)
        #endif
        Branch.getInstance().setRequestMetadataKey("$firebase_app_instance_id", value: Analytics.appInstanceID()) // App Instance ID, changes when app is reinstalled
        Branch.getInstance().setRequestMetadataKey("$firebase_user_id", value: UserStateManager.shared.firebaseUID)
        let isEEAregion = Locale.current.regionCode == "US" ? false : true // https://help.branch.io/developers-hub/docs/ios-advanced-features#google-dma-compliance
        Branch.setDMAParamsForEEA(isEEAregion, adPersonalizationConsent: adsPesonalizationConsent, adUserDataUsageConsent: false)
        BranchScene.shared().initSession(launchOptions: AppUtil.shared.savedLaunchOptions, registerDeepLinkHandler: { _, error, _ in
            if let error = error {
                logError("Couldn't initialize Branch with error: \(error)")
            } else {
                logInfo("Branch initialized with DMA params: eeaRegion: \(isEEAregion), AdPersonalizationConsent: \(adsPesonalizationConsent), AdUserDataUsageConsent: false")
            }
        })
    }

It is hard to tell about "install" and "open" events, because they are expected to come many times in all environments. However, I have noticed that the PURCHASE event is sometimes sent to the LIVE environment when no real purchases were made in Production (but there were purchases made in dev environment).

This happens sporadically, most of the time events go to correct "live" or "test" destinations. For businesses with big num of clients and smaller checks such a deviation might not be an issue, but we have small amount of users doing big checks - this makes us very sensitive to deviations like these.

Is there a way to ensure the Branch.setUseTestBranchKey(true) is be more reliable without workarounds (like temporary removing the "test" key from the .plist file when I build for Production)? Or maybe am I using setUseTestBranchKey() in a wrong way during initialization?

Steps to reproduce

  1. Setup "live" and "test" keys in .plist file
  2. Use the setUseTestBranchKey(true) method to make SDK use the "test" key

for example:

        Branch.setUseTestBranchKey(true)
        Branch.getInstance().enableLogging(at: .warning)
        Branch.getInstance().setRequestMetadataKey("$firebase_app_instance_id", value: Analytics.appInstanceID())
        Branch.getInstance().setRequestMetadataKey("$firebase_user_id", value: UserStateManager.shared.firebaseUID)
        let isEEAregion = Locale.current.regionCode == "US" ? false : true // https://help.branch.io/developers-hub/docs/ios-advanced-features#google-dma-compliance
        Branch.setDMAParamsForEEA(isEEAregion, adPersonalizationConsent: adsPesonalizationConsent, adUserDataUsageConsent: false)
        BranchScene.shared().initSession(launchOptions: AppUtil.shared.savedLaunchOptions, registerDeepLinkHandler: { _, error, _ in
            ()
        })
  1. make sure the app reports a well-visible custom event and check were those event appears

Actual Result: most of the time the event is reported to the TEST environment, but sometimes it can be seen erroneously reported to the LIVE environment:

Screenshot 2024-03-27 at 18 11 41

Expected behavior

The event initialized with setUseTestBranchKey(true) is never expected to appear in the LIVE environment and is not expected to interfere with data from production.

SDK Version

3.3.0

XCode Version

15.0

Device

iPhone 12 mini ("iPhone13,1"), iOS 17.2.1

OS

13.6.5

Additional Information/Context

No response

@echo-branch
Copy link
Contributor

@vitalii-tym
That's rather odd. The flatness of that purchase event makes me wonder if there's a nightly regression using a special build that could be causing this.

Mind filing a support ticket so we can go into more details about your specific setup? Thanks.

@vitalii-tym
Copy link
Author

Ticket submitted. Case number is 00379841.
I have also made an export of data and analyzed it carefully - the id of the user mentioned in the PURCHASE event is from our Staging server (app was installed via TestFlight), which means it was indeed supposed to use the "test" key and send it to the TEST environment.

@vitalii-tym vitalii-tym changed the title Sometimes test events are found to be reported to live environment Branch.setUseTestBranchKey(true) is ignored during initialization and all events reported into LIVE environment if Branch.getInstance() called before the initialization at least once May 2, 2024
@vitalii-tym
Copy link
Author

vitalii-tym commented May 2, 2024

I have run an additional debugging session and found that:
(1) after implementation of Delayed Initialization (as described here) it happens that my code calls Branch.getInstance().logout() and Branch.getInstance().setIdentity(uid) methods before the initialization happens.

(2) the fact that these calls are made prematurely isn't a big problem, because logout(), for example, has a double-check if (self.initializationStatus == BNCInitStatusUninitialized) and then it simply does nothing (though it happens very implicitly, very hard to notice that the method call went in vain, unless Branch logger mode turned on).

(3) even though these premature getInstance() calls don't affect anything much, they seem to still do some kind of initialization behind the scenes which picks up the LIVE key from .plist by default. The biggest problem here is that the delayed initialization routine that goes next doesn't pick up the TEST key, so that all the events are reported into LIVE environment.

@vitalii-tym vitalii-tym changed the title Branch.setUseTestBranchKey(true) is ignored during initialization and all events reported into LIVE environment if Branch.getInstance() called before the initialization at least once Branch.setUseTestBranchKey(true) is ignored during initialization and all events reported into LIVE environment if Branch.getInstance() called before the initialization May 2, 2024
@vitalii-tym
Copy link
Author

vitalii-tym commented May 2, 2024

As a workaround I have tried to move the setUseTestBranchKey(true) to be performed as early in the code as possible. In my case it is located in scene(_:willConnectTo:options:). It looks like TEST key is properly picked up in this case.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard (scene as? UIWindowScene) != nil else { return }

    #if DEV || STAGE
    Branch.setUseTestBranchKey(true)
    Branch.getInstance().enableLogging(at: .warning)
    #endif
    // Branch.io, Workaround for SceneDelegate `continueUserActivity` not getting called on cold start:
    if let userActivity = connectionOptions.userActivities.first {
        BranchScene.shared().scene(scene, continue: userActivity)
    } else if !connectionOptions.urlContexts.isEmpty {
        BranchScene.shared().scene(scene, openURLContexts: connectionOptions.urlContexts)
    }
    
}

If it is not a bug but a deliberately designed behavior, I suggest to revise the piece of documentation about "Branch Test Key", which recommends to place this piece of code "before the initSession() method". With high probability this can become an issue for everyone who have delayed initialization implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants