Skip to content

Commit ccd78b9

Browse files
committed
fix(messaging, ios): register for notifications on permission grant
Related #7272 - the only difference between react-native-permissions and our requestPermission implementation was an immediate registration for notifications after a successful grant Assuming you would never request permission if you did not want to receive notifications, we now copy this behavior This allows messaging registration and APNS token tests to pass again on capable simulators (after altering tests to use the new permission behavior)
1 parent 1f86483 commit ccd78b9

File tree

2 files changed

+35
-32
lines changed

2 files changed

+35
-32
lines changed

packages/messaging/e2e/messaging.e2e.js

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ async function isAPNSCapableSimulator() {
3737
}
3838

3939
describe('messaging()', function () {
40+
before(async function () {
41+
// our device registration tests require permissions. Set them up
42+
await firebase.messaging().requestPermission({
43+
alert: true,
44+
badge: true,
45+
sound: true,
46+
provisional: true,
47+
});
48+
});
49+
4050
describe('firebase v8 compatibility', function () {
4151
describe('namespace', function () {
4252
it('accessible from firebase.app()', function () {
@@ -98,8 +108,6 @@ describe('messaging()', function () {
98108
if (device.getPlatform() === 'ios') {
99109
await firebase.messaging().unregisterDeviceForRemoteMessages();
100110
should.equal(firebase.messaging().isDeviceRegisteredForRemoteMessages, false);
101-
// did this happen in logs?
102-
// 2024-02-02 18:35:26.277 Df testing[26266:18d3f] (Detox) 10.20.0 - [FirebaseMessaging][I-FCM002022] Declining request for FCM Token since no APNS Token specified
103111
tryToRegister = await isAPNSCapableSimulator();
104112
if (tryToRegister) {
105113
await firebase.messaging().registerDeviceForRemoteMessages();
@@ -112,27 +120,21 @@ describe('messaging()', function () {
112120
});
113121

114122
describe('hasPermission', function () {
115-
it('returns true android (default)', async function () {
116-
if (device.getPlatform() === 'android') {
117-
should.equal(await firebase.messaging().hasPermission(), true);
118-
} else {
119-
this.skip();
120-
}
121-
});
122-
123-
it('returns -1 on ios (default)', async function () {
124-
if (device.getPlatform() === 'ios') {
125-
should.equal(await firebase.messaging().hasPermission(), -1);
126-
}
123+
// we request permission in a before block, so both should be truthy
124+
it('returns truthy', async function () {
125+
should.equal(!!(await firebase.messaging().hasPermission()), true);
127126
});
128127
});
129128

130129
describe('requestPermission', function () {
131-
it('resolves 1 on android', async function () {
130+
// we request permission in a before block
131+
it('resolves correctly for default request', async function () {
132132
if (device.getPlatform() === 'android') {
133-
should.equal(await firebase.messaging().requestPermission(), 1);
133+
// our default resolve on android is "authorized"
134+
should.equal(await firebase.messaging().requestPermission({ provisional: true }), 1);
134135
} else {
135-
this.skip();
136+
// our default request on iOS results in "provisional"
137+
should.equal(await firebase.messaging().requestPermission({ provisional: true }), 2);
136138
}
137139
});
138140
});
@@ -585,30 +587,22 @@ describe('messaging()', function () {
585587
});
586588

587589
describe('hasPermission', function () {
588-
it('returns true android (default)', async function () {
590+
it('returns true', async function () {
591+
// our before block requests permission, so both should be truthy
589592
const { getMessaging, hasPermission } = messagingModular;
590-
if (device.getPlatform() === 'android') {
591-
should.equal(await hasPermission(getMessaging()), true);
592-
} else {
593-
this.skip();
594-
}
595-
});
596-
597-
it('returns -1 on ios (default)', async function () {
598-
const { getMessaging, hasPermission } = messagingModular;
599-
if (device.getPlatform() === 'ios') {
600-
should.equal(await hasPermission(getMessaging()), -1);
601-
}
593+
should.equal(!!(await hasPermission(getMessaging())), true);
602594
});
603595
});
604596

605597
describe('requestPermission', function () {
606-
it('resolves 1 on android', async function () {
598+
it('resolves correctly for default request', async function () {
607599
const { getMessaging, requestPermission } = messagingModular;
600+
// our before block requests, android will always be 1
608601
if (device.getPlatform() === 'android') {
609602
should.equal(await requestPermission(getMessaging()), 1);
610603
} else {
611-
this.skip();
604+
// ... and iOS should always be 2 (provisional)
605+
should.equal(await requestPermission(getMessaging(), { provisional: true }), 2);
612606
}
613607
});
614608
});

packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ - (NSDictionary *)constantsToExport {
284284
if (error) {
285285
[RNFBSharedUtils rejectPromiseWithNSError:reject error:error];
286286
} else {
287+
// if we do not attempt to register immediately, registration fails
288+
// later unknown reason why, but this was the only difference between
289+
// using a react-native-permissions vs built-in permissions request in
290+
// a sequence of "request permissions" --> "register for messages" you
291+
// only want to request permission if you want to register for
292+
// messages, so we register directly now - see #7272
293+
dispatch_async(dispatch_get_main_queue(), ^{
294+
[[UIApplication sharedApplication] registerForRemoteNotifications];
295+
});
287296
[self hasPermission:resolve:reject];
288297
}
289298
}];

0 commit comments

Comments
 (0)