Skip to content

Commit 80f77aa

Browse files
elizabit-bYour Nameclaude
authored
fix: handle non-array action/intent-filter in AndroidManifest parsing (#415)
* fix: handle non-array action and intent-filter in AndroidManifest parsing XML parsers like xml2js (used by @expo/config-plugins) may return a single object instead of an array when there is only one child element. The hasExistingFcmService check assumed action and intent-filter were always arrays, causing a TypeError on Expo SDK 55 for versions > 9.6.3. Normalize both fields with [].concat() before calling .some() so the check works regardless of whether the XML parser returns an object or an array. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: fix prettier formatting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Your Name <your.email@intercom.io> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1fb3ee5 commit 80f77aa

File tree

2 files changed

+75
-7
lines changed

2 files changed

+75
-7
lines changed

__tests__/withAndroidPushNotifications.test.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,70 @@ dependencies {
351351

352352
warnSpy.mockRestore();
353353
});
354+
355+
test('detects existing FCM service when action is a single object (not array)', () => {
356+
const config = createMockConfig('com.example.myapp');
357+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation();
358+
359+
config.modResults.manifest.application[0].service.push({
360+
'$': {
361+
'android:name': '.ExistingFcmService',
362+
'android:exported': 'true',
363+
},
364+
'intent-filter': [
365+
{
366+
action: {
367+
$: {
368+
'android:name': 'com.google.firebase.MESSAGING_EVENT',
369+
},
370+
},
371+
},
372+
],
373+
} as any);
374+
375+
withAndroidPushNotifications(config as any, {} as any);
376+
377+
const services = config.modResults.manifest.application[0].service;
378+
expect(services).toHaveLength(1);
379+
expect(services[0].$['android:name']).toBe('.ExistingFcmService');
380+
expect(warnSpy).toHaveBeenCalledWith(
381+
expect.stringContaining('existing FirebaseMessagingService')
382+
);
383+
384+
warnSpy.mockRestore();
385+
});
386+
387+
test('detects existing FCM service when intent-filter is a single object (not array)', () => {
388+
const config = createMockConfig('com.example.myapp');
389+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation();
390+
391+
config.modResults.manifest.application[0].service.push({
392+
'$': {
393+
'android:name': '.ExistingFcmService',
394+
'android:exported': 'true',
395+
},
396+
'intent-filter': {
397+
action: [
398+
{
399+
$: {
400+
'android:name': 'com.google.firebase.MESSAGING_EVENT',
401+
},
402+
},
403+
],
404+
},
405+
} as any);
406+
407+
withAndroidPushNotifications(config as any, {} as any);
408+
409+
const services = config.modResults.manifest.application[0].service;
410+
expect(services).toHaveLength(1);
411+
expect(services[0].$['android:name']).toBe('.ExistingFcmService');
412+
expect(warnSpy).toHaveBeenCalledWith(
413+
expect.stringContaining('existing FirebaseMessagingService')
414+
);
415+
416+
warnSpy.mockRestore();
417+
});
354418
});
355419

356420
describe('error handling', () => {

src/expo-plugins/withAndroidPushNotifications.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,17 @@ const registerServiceInManifest: ConfigPlugin<IntercomPluginProps> = (
152152
const hasExistingFcmService = mainApplication.service?.some(
153153
(s) =>
154154
s.$?.['android:name'] !== serviceName &&
155-
s['intent-filter']?.some(
156-
(f: any) =>
157-
f.action?.some(
158-
(a: any) =>
159-
a.$?.['android:name'] === 'com.google.firebase.MESSAGING_EVENT'
160-
)
161-
)
155+
([] as any[])
156+
.concat(s['intent-filter'] ?? [])
157+
.some((f: any) =>
158+
([] as any[])
159+
.concat(f.action ?? [])
160+
.some(
161+
(a: any) =>
162+
a.$?.['android:name'] ===
163+
'com.google.firebase.MESSAGING_EVENT'
164+
)
165+
)
162166
);
163167

164168
if (hasExistingFcmService) {

0 commit comments

Comments
 (0)