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

AWSCloudWatchLoggingCategoryClient asks for Current User Identifier During Configuration (CRASH) #3897

Open
Hartistic opened this issue Oct 13, 2024 · 9 comments
Labels
auth Issues related to the Auth category pending-maintainer-response Issue is pending response from an Amplify team member question General question

Comments

@Hartistic
Copy link

Hartistic commented Oct 13, 2024

Describe the bug

While configuring Amplify with an AWSCloudWatchLoggingPluginConfiguration and an AWSCognitoAuthPlugin configuration the library has a race condition that crashes the application 50% of the time with an error of Thread 20: Fatal error: Authentication category is not configured. Call Amplify.configure() before using any methods on the category.

The problem is that these two configurations are added to Amplify and this crash occurs when calling Amplify.configure().

Order of Methods that causes crash to occur:

  1. try configure(CategoryType.logging.category, using: resolvedConfiguration)
  2. try configurable.configure(using: configuration)
  3. try configure(using: categoryConfiguration(from: amplifyConfiguration))
  4. try Amplify.configure(plugins: Array(plugins.values), using: configuration)
  5. try plugin.configure(using: pluginConfiguration)
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
            self.loggingClient.takeUserIdentifierFromCurrentUser()
        }
func takeUserIdentifierFromCurrentUser() {
        Task {
            do {
                let user = try await authentication.getCurrentUser()
                self.userIdentifier = user.userId
            } catch {
                self.userIdentifier = nil
            }
            self.updateSessionControllers()
        }
    }
public func getCurrentUser() async throws -> AuthUser {
        try await plugin.getCurrentUser()
    }
return Fatal.preconditionFailure(
                """
                \(categoryType.displayName) category is not configured. Call Amplify.configure() before using \
                any methods on the category.
                """
            )

Steps To Reproduce

Steps to reproduce the behavior:
1. Add AWSCloudWatchLoggingPluginConfiguration and AWSCognitoAuthPlugin to Amplify:

    private func addAuthenticationPlugin() throws {
        let authPlugin = AWSCognitoAuthPlugin(networkPreferences: Self.networkPreferences)
        do {
            try Amplify.add(plugin: authPlugin)
        } catch {
            throw error
        }
    }

    private func addCloudWatchLoggingPlugin() throws {
        do {
            let logLevels: [String: LogLevel] = ["AWSAuthFetchSessionTask": .error]
            let loggingConstraints = LoggingConstraints(defaultLogLevel: .debug, categoryLogLevel: logLevels)
            let loggingConfiguration = AWSCloudWatchLoggingPluginConfiguration(logGroupName: "your log group",
                                                                               region: "us-east-1",
                                                                               localStoreMaxSizeInMB: 1,
                                                                               flushIntervalInSeconds: 10,
                                                                               loggingConstraints: loggingConstraints)
            let plugin = AWSCloudWatchLoggingPlugin(loggingPluginConfiguration: loggingConfiguration)
            try Amplify.add(plugin: plugin)
        } catch {
            throw error
        }
    }
2. load a amplifyconfiguration.json and call configure:

    private func loadAmplifyConfiguration() throws {
        do {
            let amplifyConfig = try getLocalAmplifyConfigurationFile()
            try Amplify.configure(amplifyConfig)
        } catch {
            throw error
        }
    }
3. On iPhone 15 Pro Max and newer seems to crash way more often.

Expected behavior

The AWSCloudWatchLoggingPluginConfiguration shouldn't be asking for Authentication details during it's configuration...the library says you can only call configure() once, so configuring Auth and then Logging isn't possible.

Amplify Framework Version

2.41.1

Amplify Categories

Analytics, API, Auth

Dependency manager

Swift PM

Swift version

5.8.0

CLI version

I am not sure

Xcode version

16.0

Relevant log output

No response

Is this a regression?

Yes

Regression additional context

No response

Platforms

iOS

OS Version

IOS 18

Device

iPhone 15 Pro Max

Specific to simulators

no

Additional context

No response

@github-actions github-actions bot added pending-triage Issue is pending triage pending-maintainer-response Issue is pending response from an Amplify team member labels Oct 13, 2024
@thisisabhash thisisabhash removed the pending-triage Issue is pending triage label Oct 14, 2024
@thisisabhash
Copy link
Member

Hello,

AWSCloudWatchLoggingPlugin needs Auth Plugin to be configured. You'd need to setup Amplify Auth through CLI by following steps here: https://docs.amplify.aws/gen1/swift/build-a-backend/auth/set-up-auth/

Then you can setup AWSCloudWatchLoggingPlugin by following steps here: https://docs.amplify.aws/gen1/swift/build-a-backend/more-features/logging/set-up-logging/

import Amplify
import AWSCognitoAuthPlugin
import AWSCloudWatchLoggingPlugin

private func addCloudWatchLoggingPlugin() throws {
    do {
        let logLevels: [String: LogLevel] = ["AWSAuthFetchSessionTask": .error]
        let loggingConstraints = LoggingConstraints(defaultLogLevel: .debug, categoryLogLevel: logLevels)
        let loggingConfiguration = AWSCloudWatchLoggingPluginConfiguration(logGroupName: "your log group",
                                                                           region: "us-east-1",
                                                                           localStoreMaxSizeInMB: 1,
                                                                           flushIntervalInSeconds: 10,
                                                                           loggingConstraints: loggingConstraints)
        let plugin = AWSCloudWatchLoggingPlugin(loggingPluginConfiguration: loggingConfiguration)
        try Amplify.add(plugin: plugin)
    } catch {
        throw error
    }
}

init() {
    do {
        try Amplify.add(plugin: AWSCognitoAuthPlugin())
        try addCloudWatchLoggingPlugin()
        try Amplify.configure()
    } catch {
        assert(false, "Error initializing Amplify: \(error)")
    }
}

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Oct 14, 2024
@thisisabhash thisisabhash added bug Something isn't working auth Issues related to the Auth category question General question and removed bug Something isn't working labels Oct 14, 2024
@Hartistic
Copy link
Author

Hartistic commented Oct 15, 2024

Thank you so much for the quick response @thisisabhash, we are not using the CLI and Auth is already setup. I think the main culprit seems to be this:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
        self.loggingClient.takeUserIdentifierFromCurrentUser()
}

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Oct 15, 2024
@harsh62
Copy link
Member

harsh62 commented Oct 15, 2024

@Hartistic Can you share where addAuthenticationPlugin and addCloudWatchLoggingPlugin is being used in your project?

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Oct 15, 2024
@Hartistic
Copy link
Author

Absolutely @harsh62, and thank you guys so much, Im actually hoping I am just doing something out of order and that this is an easy resolution.

We have a SwiftUI Application.

1). On App Launch:

  • We start listening to the Auth hub first (this way we know when Amplify Configuration finishes):
 self.unsubscribeToken = Amplify.Hub.listen(to: .auth) { payload in
      UserStateMachine.shared.handleEvent(payload)
}
  • Next we add all the plugins we need to Amplify:
       // Authentication:
       try addAuthenticationPlugin()
       // Notifications:
       try addNotificationPlugin()
       // Cloud Logging:
       try addCloudWatchLoggingPlugin()
       // Pinpoint Analytics:
       try addAnalyticsPlugin()
       // AWS API:
       try addAPIPlugin()
  • Next we call Amplify.configure (we load our amplifyconfiguration.json file locally that has our specific settings)
   private func loadAmplifyConfiguration() throws {
        do {
            let amplifyConfig = try self.loadConfiguration() // Loads JSON file
            try Amplify.configure(amplifyConfig)
        } catch {
            throw error
        }
    }
  • Once try await for configuring is done we immediately call a force refresh:
    /// Check The Auth Session:
    func forceRefreshAuthSession() async throws {
        let plugin = try getAWSCognitoAuthPlugin()
        let session = try await plugin.fetchAuthSession(options: .forceRefresh())
        print("::: AUTH PLUGIN: AMPLIFY USER SESSION IS SIGNED IN - \(session.isSignedIn)")
    }

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Oct 15, 2024
@harsh62
Copy link
Member

harsh62 commented Oct 15, 2024

Got it and why do you suspect that the following snippet is a problem?

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
     self.loggingClient.takeUserIdentifierFromCurrentUser()
}

From what I see is that the Auth plugin is being configured before the logging plugin, so this snippet should work, because Auth is already configured.

Are you able to share symbolicated crash log too?

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Oct 15, 2024
@Hartistic
Copy link
Author

@harsh62 absolutely, I cannot share it on this thread, could I share it with you privately somehow?

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Oct 15, 2024
@Hartistic
Copy link
Author

Got it and why do you suspect that the following snippet is a problem?

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
     self.loggingClient.takeUserIdentifierFromCurrentUser()
}

From what I see is that the Auth plugin is being configured before the logging plugin, so this snippet should work, because Auth is already configured.

@harsh62 my crash backtraces lead back to that code block.

@martzcodes
Copy link

@harsh62 I work with @Hartistic ... IIRC the issue has to do with CloudWatch asking Auth for the user id and it's doing it in a way that when Auth gets an error because we don't have a UserPool it crashes. We're using Identity Pools only for federated logins using Sign in with Apple (no User Pools)

@Hartistic
Copy link
Author

Hartistic commented Oct 15, 2024

@harsh62 my Slack is: [email protected] if that helps

Crash Message : Thread 14: Fatal error: Authentication category is not configured. Call Amplify.configure() before using any methods on the category.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issues related to the Auth category pending-maintainer-response Issue is pending response from an Amplify team member question General question
Projects
None yet
Development

No branches or pull requests

4 participants