aws-amplify / amplify-swift

A declarative library for application development using cloud services.
Apache License 2.0
447 stars 194 forks source link

Allow Retrieval of Pinpoint EndpointId #3478

Open Peyton-McKee opened 8 months ago

Peyton-McKee commented 8 months ago

Is your feature request related to a problem? Please describe.

I want to be able to get my users Pinpoint endpointId to be able to store it in order to send direct messages to their endpoint on some app events. However I am unable to find any methods that give me the ability to do that. From the escape hatch on Analytics I see there’s a getEndpoint function on the PinpointClientProtocol however that requires an application id and an endpointId which is exactly what i need!

Describe the solution you'd like

A function that allows you to retrieve the users endpointId for their userId of device token or something.

Describe alternatives you've considered

Ive considered storing the device token however that wont let me send push notifications as the sendmessages function seems to require endpointIds.

Is the feature request related to any of the existing Amplify categories?

Analytics, Auth

Additional context

If there’s any documentation on actually sending push notifications programatically not just receiving them somewhere from a device that would be awesome to know the location of been really struggling to find anything.

github-actions[bot] commented 8 months ago

This has been identified as a feature request. If this feature is important to you, we strongly encourage you to give a 👍 reaction on the request. This helps us prioritize new features most important to you. Thank you!

phantumcode commented 8 months ago

Thank you for submitting the feature request. Our team will prioritize it and will post an update once we have more information.

Peyton-McKee commented 8 months ago

After review of this link https://docs.aws.amazon.com/pinpoint/latest/developerguide/send-messages-push.html, I was able to send a message using the device token + an AWS Lambda, would love some additional support for sending notifications from directly within a swift app without having to use lambda function.

ruisebas commented 8 months ago

Hi @Peyton-McKee! There is currently no API that directly provides the values you need to manipulate the endpoint used by Amplify (i.e. applicationId and endpointId), so we will use this feature request to track that addition. In the meantime, there are others ways to retrieve them.

The applicationId is the appId value you have in your amplifyconfiguration.json file, under analytics.plugins.awsPinpointAnalyticsPlugin.pinpointAnalytics. You should be able to retrieve it from there:

"analytics": {
    "plugins": {
        "awsPinpointAnalyticsPlugin": {
            "pinpointAnalytics": {
                "appId": "[THIS IS THE APPLICATION ID]",
                "region": "[region]"
            }
        }
    }
}

The endpointId is stored in the Keychain with "com.amazonaws.AWSPinpointContextKeychainUniqueIdKey" as account and "com.amazonaws.AWSPinpointContext" as service. Here's a function you can use to retrieve it:

private func fetchEndpointId() -> String? {
    let query: [String: Any] = [
        String(kSecAttrAccount): "com.amazonaws.AWSPinpointContextKeychainUniqueIdKey",
        String(kSecAttrService): "com.amazonaws.AWSPinpointContext",
        String(kSecClass): String(kSecClassGenericPassword),
        String(kSecMatchLimit): kSecMatchLimitOne,
        String(kSecUseDataProtectionKeychain): true,
        String(kSecReturnData): true,
    ]

    var result: AnyObject?
    guard SecItemCopyMatching(query as CFDictionary, &result) == errSecSuccess,
          let data = result as? Data else {
        return nil
    }

    return String(decoding: data, as: UTF8.self)
}

Once you have both applicationId and endpointId, you can then just grab the PinpointClientProtocol from either the Analytics or the Push Notifications plugin (as they share the same endpoint) and directly call the APIs you need (e.g. getEndpoint(input:) and sendMessages(input:))