Recently upgraded to Expo 39 and switched to the new expo-notifications. When receiving a push notification on an Android device (standalone APK built by Expo, Pixel 2, Android 11) - no notification is displayed.
I see this error in logcat (redacted credentials):
“expo-notifications: No experience found for id @username/appname”
Notifications work fine when running the app via Expo (expo start), on iOS and Android. They are received and displayed.
I see that Notifications.getExpoPushTokenAsync() can take experienceId as a param, but managed workflow does not require it, and “Constants.manifest.id” matches what I’m expecting.
I have set app.json to use the new API:
android {
“useNextNotificationsApi”: true,
I’ve read through the guide and API to no avail:
What is the experienceId? Do I need to register it somewhere? Is it okay to run an APK standalone on the same phone as Expo app?
I’ve been testing and working on expo-notifications on SDK 39 recently and haven’t seen this error, so it would help if you shared some code. It’s good to know you have useNextNotificationApi already set, but what’s your client-side notifications logic look like? Specifically, make sure you’re not pulling in {Notifications} from 'expo' anywhere anymore.
@charliecruzan Thanks for reaching out. The scenario is that I’ve got one codebase that we whitelabel for different clients. In our oldest brand I can run an android build, sideload the apk, and notifications work on the app. I then switch out the branding, app.json (to pull in new ios.bundleIdentifier, android.package, and expo.slug), run the build, sideload and notifications do not work. Running adb logcat I get the following when the notification is pushed to the device and arrives, but fails to do anything.
10-01 00:30:47.607 874 879 E statsd : Predicate 5980654721335871649 dropping data for dimension key (10)0x2010101->10350[I] (10)0x30000->GOOGLE_C2DM[S]
10-01 00:30:47.628 28601 30050 E expo-notifications: No experience found for id @<myuser>/<myappname>
10-01 00:30:47.642 874 879 E statsd : Predicate 5980654721335871649 dropping data for dimension key (10)0x2010101->10350[I] (10)0x30000->GOOGLE_C2DM[S]
Both apps have their own google-services.json connected to their own Firebase projects. Likewise, both apps have their own FCM API keys loaded to expo. I see in here where this is coming from, but I’m not sure where the ExponentDB is being populated and why it doesn’t have the correct ExperienceID.
that’s very odd, so it looks like that entry should be saved in the database when your app launches an update (which it should do on app open), but maybe you can manually trigger that to happen with an OTA update?
We’ve always had OTA updates disabled in app.json. Here are some of the errors that are firing the first time the app launches.
10-01 16:00:37.952 19879 19879 E ExperienceActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'host.exp.exponent.j host.exp.exponent.j.c(java.lang.String, java.lang.Object[])' on a null object reference
10-01 16:00:38.402 19879 19955 E Expo : Cannot initialize app loader. host.exp.exponent.taskManager.ExpoHeadlessAppLoader
10-01 16:00:38.402 19879 19955 W System.err: java.lang.ClassNotFoundException: host.exp.exponent.taskManager.ExpoHeadlessAppLoader
10-01 16:00:38.404 19879 19955 W System.err: at java.lang.Class.classForName(Native Method)
10-01 16:00:38.404 19879 19955 W System.err: at java.lang.Class.forName(Class.java:454)
10-01 16:00:38.404 19879 19955 W System.err: at java.lang.Class.forName(Class.java:379)
10-01 16:00:38.404 19879 19955 W System.err: at l.d.a.a.a(AppLoaderProvider.java:2)
10-01 16:00:38.404 19879 19955 W System.err: at l.d.a.a.b(AppLoaderProvider.java:2)
10-01 16:00:38.404 19879 19955 W System.err: at expo.modules.taskManager.TaskService.getAppLoader(TaskService.java:2)
10-01 16:00:38.404 19879 19955 W System.err: at expo.modules.taskManager.TaskService.isStartedByHeadlessLoader(TaskService.java:1)
Actually, those errors all fire in both versions of the app I’m testing, but one does receive push notifications. Any other way to debug what could be preventing the loading of the Experience info into that DB?
Well we can double-check that the experience ID is correct. Constants.manifest.id should match the value you’re seeing the error logs (I know @gregchain already mentioned he did this, just want to make sure) . @bitzlato it should match the experience ID you’re sending to FCM, as well.
@bitzlato in your issue you said addNotificationResponseReceivedListener, but are the actual notifications coming through or not?
I would try finding the the differences between the two projects you have (1 that works and one that doesn’t), share them here, and also apply them atomically until you find what change result in the “no experience found” error
Finally got it working. After digging through the Android code a lot more it started looking like this had something to do with the AppLoader. We’ve run with OTA updates disabled for a couple of years because we want to manually control how things are released through the stores. Once we set updates.enabled to true, the notifications started working again. This is the line that sent me down this path specifically: expo/AppLoader.java at de84b5ff98b412f63a7e77d6f1e08579eb651d82 · expo/expo · GitHub
Here’s the change in app.json that was required. It’s worth nothing that we’d still much rather have updates disabled, but the need for notifications is significantly more important right now.
@charliecruzan Actually both were using the same setting with updates disabled. However, the older app (created on expo.io about 2 years ago) was working fine. I’m curious if there’s any kind of internal Android caching mechanism that would be causing this, or something different stored within Expo’s build process that’s different for an older app.
Also, the older app used to work with legacy notifications (no FCM/google-services.json), but was upgraded to the next-gen notifications with FCM/google-services.json. The new app has only ever existed since next-gen notifications. Could be part of the difference perhaps.