Closed julian-dotcom closed 1 week ago
As an update, if I comment out / remove this if statement if (!(await getEndpointId(appId, 'PushNotification'))) {
the endpoint creation works as expected.
node_modules/@aws-amplify/notifications/src/pushNotifications/providers/pinpoint/apis/identifyUser.native.ts
export const identifyUser: IdentifyUser = async ({
userId,
userProfile,
options,
}) => {
assertIsInitialized();
const { credentials, identityId } = await resolveCredentials();
const { appId, region } = resolveConfig();
const { address, optOut, userAttributes } = options ?? {};
if (!(await getEndpointId(appId, 'PushNotification'))) {
// if there is no cached endpoint id, wait for successful endpoint creation before continuing
await getInflightDeviceRegistration();
}
await updateEndpoint({
address,
channelType: getChannelType(),
optOut,
appId,
category: 'PushNotification',
credentials,
identityId,
region,
userAttributes,
userId,
userProfile,
userAgentValue: getPushNotificationUserAgentString(
PushNotificationAction.IdentifyUser,
),
});
};
So it seems like the getInflightDeviceRegistration
function fails, but it never throws an error or informs the developer what goes wrong.
As an update, I tried logging from the resolveInflightDeviceRegistration
and rejectInflightDeviceRegistration
but they are never called by the getInflightDeviceRegistration
in node_modules/@aws-amplify/notifications/src/pushNotifications/providers/pinpoint/utils/inflightDeviceRegistration.ts
import { PushNotificationError } from '../../../errors';
import {
InflightDeviceRegistration,
InflightDeviceRegistrationResolver,
} from '../types';
const inflightDeviceRegistrationResolver: InflightDeviceRegistrationResolver =
{};
let inflightDeviceRegistration: InflightDeviceRegistration = new Promise<void>(
(resolve, reject) => {
inflightDeviceRegistrationResolver.resolve = resolve;
inflightDeviceRegistrationResolver.reject = reject;
},
);
export const getInflightDeviceRegistration = () => inflightDeviceRegistration;
export const resolveInflightDeviceRegistration = () => {
inflightDeviceRegistrationResolver.resolve?.();
// release promise from memory
inflightDeviceRegistration = undefined;
};
export const rejectInflightDeviceRegistration = (underlyingError: unknown) => {
inflightDeviceRegistrationResolver.reject?.(
new PushNotificationError({
name: 'DeviceRegistrationFailed',
message: 'Failed to register device for push notifications.',
underlyingError,
}),
);
// release promise from memory
inflightDeviceRegistration = undefined;
};
I investigated some more and figured what goes wrong. To me, it looks like a bug.
When calling initializePushNotifications()
in my index.js
, the function calls addNativeListeners()
, which calls addTokenEventListener()
, which calls registerDevice()
.
The problem is that the register device function fails until a user is authenticated. This is fine and makes sense.
However, the issue is that the exception is not passed on to initializePushNotifications()
. This function continues and calls initialize()
, setting initialized
to true
.
This incorrect behavior because the device was never successfully registered, but the code now thinks it's initialized.
Hence, whenever calling initializePushNotifications()
after, the code just exits the function early and nothing happens.
In my estimation, this should not happen. We should set initialized
to true, ONLY if the device was successfully registered.
export const initializePushNotifications = (): void => {
if (isInitialized()) {
logger.info('Push notifications have already been enabled');
console.log('Push notifications already initialized')
return;
}
addNativeListeners();
addAnalyticsListeners();
initialize();
};
Source: node_modules/@aws-amplify/notifications/src/pushNotifications/providers/pinpoint/apis/initializePushNotifications.native.ts
It seems like the ticket is related to my other open issue. We should continue the conversation in this thread for simplicity.
@julian-dotcom per your suggestions above, closing this in favor of your other issue.
Sorry for the confusion/misunderstanding, but I think we should continue in this thread right here, and close the other one.
Before opening, please confirm:
JavaScript Framework
React Native
Amplify APIs
Analytics, Push Notifications
Amplify Version
v6
Amplify Categories
notifications
Backend
None
Environment information
Describe the bug
identifyUser
fromaws-amplify/push-notifications
never successfully saves the endpoint with the address on first launch.It never registers the endpoint, until I close the app and restart it with the user already authenticated. On second launch, it succesfully submits the endpoint on Android, but never does on iOS.
Expected behavior
I sign in and upon sign in, the
identifyUser
registers the endpoint on first call, allowing me to receive notifications.Reproduction steps
unexpected behavior arises when I call
identifyUser
Code Snippet
My index.js
How I register the device token:
identifyUser
call the function in this file/node_modules/@aws-amplify/notifications/src/pushNotifications/providers/pinpoint/apis/identifyUser.native.ts
where unfortunately,await getEndpointId(appId, 'Analytics')
returnsundefined
Log output
aws-exports.js
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response