Repository navigation
Conversation
USER and REALM push target expansion no longer requires a non-empty FCM token in the asset query, so sendMessage can persist the existing "No FCM token found for console" failure instead of MISSING_TARGETS. Fixes openremote#3113
ab6e846 to
a28cc9f
Compare
MartinaeyNL
left a comment
There was a problem hiding this comment.
First of all, thank you for creating a pull request! 🥳
You need to sign the contributor license agreement as stated by the bot above 😉
I'm happy to take a look after that's been resolved.
The dev-mode skip returned before the token check, so a user target with no token looked like success in integration tests.
…get-missing-fcm-error
|
CLA is signed ( The missing-FCM-token check now runs before the dev-mode skip. In the last integration run, The two |
Ekhorn
left a comment
There was a problem hiding this comment.
This is an initial AI-assisted review.
The new step for a user whose consoles all lack a token covers the scenario from #3113, and checking the token before the dev-mode skip makes dev mode record the same failure as production.
Removing the token predicate from target expansion goes beyond the issue, though: browser and anonymous consoles, which never have an FCM token, become USER and REALM targets, so ordinary sends to those targets return 400 and store a failed notification per browser console. Details inline.
| false, | ||
| new NameValuePredicate.Path( | ||
| PushNotificationMessage.TYPE, "data", "token"))); | ||
| .types(ConsoleAsset.class); |
There was a problem hiding this comment.
Dropping the token predicate widens USER, REALM and linked-user ASSET expansion to every console asset, not just FCM consoles that lost their token:
- Every browser that loads the manager registers a console whose
pushprovider has versionweband never carries a token (ui/component/core/src/console.ts:486-500), and manager/src/main/java/org/openremote/manager/asset/console/ConsoleResourceImpl.java:177-183 links it to the logged-in user. Anonymous browser consoles and consoles without anypushprovider are included too. - Each of these consoles fails with "No FCM token found for console", and one failed target makes the whole exchange return
false(manager/src/main/java/org/openremote/manager/notification/NotificationService.java:359-362), sosendNotificationanswers 400 even when the user's phone received the push. The rewritten step at test/src/test/groovy/org/openremote/test/notification/NotificationTest.groovy:398-408 shows this:testuser3Console2still has a token, yet the send that used to succeed now expects 400. - A REALM broadcast now stores one failed
SentNotificationfor every browser console in the realm on each send, and runs the per-console user query for each of them.
To keep the fix scoped to #3113, the token-less consoles could be mapped only when no console with a token is found for a target, so MISSING_TARGETS is replaced by a recorded failure without changing the result of normal sends. Limiting expansion to consoles whose push provider is fcm, the rule isLinkedToFcmProvider (manager/src/main/java/org/openremote/manager/notification/PushNotificationHandler.java:602-611) applies in start(), would also keep browser consoles out. A REALM step with a token-less console in the spec would pin down whichever behavior is chosen.
| testUser3Console2Asset.getConsoleProviders().map { | ||
| it.get(PushNotificationMessage.TYPE) | ||
| }.get().getData().put("token", null) | ||
| assetStorageService.merge(testUser3Console2Asset) |
There was a problem hiding this comment.
The handler's token cache is updated by an asynchronous route on PERSISTENCE_TOPIC (a SEDA endpoint), so this send can still read the old token for testuser3Console2. When it does, that console is sent without an error and the console2Notifications assertion below times out. The step that clears the token on testuser3Console1 already waits for the cache before sending; the same wait here removes the race:
| assetStorageService.merge(testUser3Console2Asset) | |
| assetStorageService.merge(testUser3Console2Asset) | |
| conditions.eventually { | |
| assert pushNotificationHandler.consoleFCMTokenMap.get(testUser3Console2Asset.id) == null | |
| } |
…t-missing-fcm-error
A normal user or realm send still targets consoles that have an FCM token. When none do, map FCM consoles so the missing token is recorded instead of a missing-targets error, and wait for the token cache before that send.
…-error' into fix/3113-user-target-missing-fcm-error
|
Addressed the review on tip
|
|



Description
Fixes #3113
When a push notification was sent to a
USERorREALMtarget, console assets were only included in target mapping if they already had a non-empty FCM token inCONSOLE_PROVIDERS. Consoles without a token were dropped during mapping, which led to an empty target list and the misleadingMISSING_TARGETS/ "Notification targets must be set" error.Direct
ASSETconsole targets already kept consoles without a token soPushNotificationHandler.sendMessagecould record No FCM token found for console: …. USER/REALM expansion now uses the same behaviour by not requiring a token in the asset query.Checklist
Test plan
./gradlew :manager:compileJava :test:compileTestGroovy(JDK 21)NotificationTestintegration spec (requiresdocker compose -f profile/dev-testing.yml -p openremote up -d --no-build; Docker stack was not running in the implementator environment)