-
Notifications
You must be signed in to change notification settings - Fork 766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix push from closed state #880
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -192,5 +192,3 @@ package-lock.json | |
|
||
.history | ||
|
||
# Typescript build | ||
lib/dist/ | ||
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -8,6 +8,7 @@ | |||||||||||||||||||||||||||||||||
import android.content.Intent; | ||||||||||||||||||||||||||||||||||
import android.os.Build; | ||||||||||||||||||||||||||||||||||
import android.os.Bundle; | ||||||||||||||||||||||||||||||||||
import android.util.Log; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
import com.facebook.react.bridge.ReactContext; | ||||||||||||||||||||||||||||||||||
import com.wix.reactnativenotifications.core.AppLaunchHelper; | ||||||||||||||||||||||||||||||||||
|
@@ -18,6 +19,7 @@ | |||||||||||||||||||||||||||||||||
import com.wix.reactnativenotifications.core.JsIOHelper; | ||||||||||||||||||||||||||||||||||
import com.wix.reactnativenotifications.core.NotificationIntentAdapter; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
import static com.wix.reactnativenotifications.Defs.LOGTAG; | ||||||||||||||||||||||||||||||||||
import static com.wix.reactnativenotifications.Defs.NOTIFICATION_OPENED_EVENT_NAME; | ||||||||||||||||||||||||||||||||||
import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME; | ||||||||||||||||||||||||||||||||||
import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_BACKGROUND_EVENT_NAME; | ||||||||||||||||||||||||||||||||||
|
@@ -207,9 +209,14 @@ private void notifyReceivedBackgroundToJS() { | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
private void notifyOpenedToJS() { | ||||||||||||||||||||||||||||||||||
Bundle response = new Bundle(); | ||||||||||||||||||||||||||||||||||
response.putBundle("notification", mNotificationProps.asBundle()); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
mJsIOHelper.sendEventToJS(NOTIFICATION_OPENED_EVENT_NAME, response, mAppLifecycleFacade.getRunningReactContext()); | ||||||||||||||||||||||||||||||||||
try | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
response.putBundle("notification", mNotificationProps.asBundle()); | ||||||||||||||||||||||||||||||||||
mJsIOHelper.sendEventToJS(NOTIFICATION_OPENED_EVENT_NAME, response, mAppLifecycleFacade.getRunningReactContext()); | ||||||||||||||||||||||||||||||||||
} catch (NullPointerException e) | ||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||
Log.e(LOGTAG, "notifyOpenedToJS: Null pointer exception"); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
Comment on lines
+212
to
+219
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It actually won't fix the issue but will only prevent the app from crashing: instead of receiving a callback on JS side it will only log the "null pointer exception" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case @artyorsh I would argue this solution is sufficient, taking into account:
A "root" cause for that might be more related to #837 , but @DanielEliraz should know more about that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely better to have it caught than having the app crashing - true. But will it mean that in the bailed cases there will be no callback on JS? I think another scenario which might be related to the issue is that this function is called twice for some reasons - first time with "good" arguments and the second time with "bad". The fix will have more sense then 🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. after some testing, @artyorsh 's guess is right. the function is called twice, first with the null bundle, then with the correct data. @DanielEliraz can we have your review please ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DanielEliraz is this being reviewed? |
||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
protected void launchOrResumeApp() { | ||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export declare class Notification { | ||
identifier: string; | ||
payload: any; | ||
constructor(payload: object); | ||
get title(): string; | ||
get body(): string; | ||
get sound(): string; | ||
get badge(): number; | ||
get type(): string; | ||
get thread(): string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Notification = void 0; | ||
class Notification { | ||
constructor(payload) { | ||
this.payload = payload; | ||
this.identifier = this.payload.identifier; | ||
} | ||
get title() { | ||
return this.payload.title; | ||
} | ||
get body() { | ||
return this.payload.body; | ||
} | ||
get sound() { | ||
return this.payload.sound; | ||
} | ||
get badge() { | ||
return this.payload.badge; | ||
} | ||
get type() { | ||
return this.payload.type; | ||
} | ||
get thread() { | ||
return this.payload.thread; | ||
} | ||
} | ||
exports.Notification = Notification; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Notification_1 = require("./Notification"); | ||
const NotificationIOS_1 = require("./NotificationIOS"); | ||
const NotificationAndroid_1 = require("./NotificationAndroid"); | ||
describe('Notification', () => { | ||
it('Should create notification with payload', () => { | ||
const payload = { p: 'p' }; | ||
const notification = new Notification_1.Notification(payload); | ||
expect(notification.payload).toEqual(payload); | ||
}); | ||
it('Should create iOS notification with identifier', () => { | ||
const payload = { identifier: 'identifier' }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.identifier).toEqual(payload.identifier); | ||
}); | ||
it('Should create Android notification with identifier', () => { | ||
const payload = { 'google.message_id': 'identifier' }; | ||
const notification = new NotificationAndroid_1.NotificationAndroid(payload); | ||
expect(notification.identifier).toEqual('identifier'); | ||
}); | ||
it('Should return title from payload', () => { | ||
const payload = { title: 'title' }; | ||
const notification = new Notification_1.Notification(payload); | ||
expect(notification.title).toEqual(payload.title); | ||
}); | ||
it('Should return body from payload', () => { | ||
const payload = { body: 'body' }; | ||
const notification = new Notification_1.Notification(payload); | ||
expect(notification.body).toEqual(payload.body); | ||
}); | ||
it('Should return sound from payload', () => { | ||
const payload = { sound: 'sound.mp4' }; | ||
const notification = new Notification_1.Notification(payload); | ||
expect(notification.sound).toEqual(payload.sound); | ||
}); | ||
it('Should return badge from payload', () => { | ||
const payload = { badge: 1 }; | ||
const notification = new Notification_1.Notification(payload); | ||
expect(notification.badge).toEqual(payload.badge); | ||
}); | ||
it('Should return type from payload', () => { | ||
const payload = { type: 'type' }; | ||
const notification = new Notification_1.Notification(payload); | ||
expect(notification.type).toEqual(payload.type); | ||
}); | ||
it('Should return thread from payload', () => { | ||
const payload = { thread: 'thread' }; | ||
const notification = new Notification_1.Notification(payload); | ||
expect(notification.thread).toEqual(payload.thread); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Notification } from './Notification'; | ||
export declare class NotificationAndroid extends Notification { | ||
constructor(payload: object); | ||
get title(): string; | ||
get body(): string; | ||
get sound(): string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.NotificationAndroid = void 0; | ||
const Notification_1 = require("./Notification"); | ||
class NotificationAndroid extends Notification_1.Notification { | ||
constructor(payload) { | ||
super(payload); | ||
this.identifier = this.payload["google.message_id"]; | ||
} | ||
get title() { | ||
return this.payload.title; | ||
} | ||
get body() { | ||
return this.payload.body; | ||
} | ||
get sound() { | ||
return this.payload.sound; | ||
} | ||
} | ||
exports.NotificationAndroid = NotificationAndroid; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const NotificationAndroid_1 = require("./NotificationAndroid"); | ||
describe('Notification', () => { | ||
it('Should create notification with payload', () => { | ||
const payload = { p: 'p' }; | ||
const notification = new NotificationAndroid_1.NotificationAndroid(payload); | ||
expect(notification.payload).toEqual(payload); | ||
}); | ||
it('Should return title from payload', () => { | ||
const payload = { title: 'title', body: 'body' }; | ||
const notification = new NotificationAndroid_1.NotificationAndroid(payload); | ||
expect(notification.title).toEqual('title'); | ||
}); | ||
it('Should return body from payload', () => { | ||
const payload = { title: 'title', body: 'body' }; | ||
const notification = new NotificationAndroid_1.NotificationAndroid(payload); | ||
expect(notification.body).toEqual('body'); | ||
}); | ||
it('Should return sound from payload', () => { | ||
const payload = { title: 'title', sound: 'sound.wav' }; | ||
const notification = new NotificationAndroid_1.NotificationAndroid(payload); | ||
expect(notification.sound).toEqual('sound.wav'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { Notification } from './Notification'; | ||
export declare class NotificationFactory { | ||
fromPayload(payload: any): Notification; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.NotificationFactory = void 0; | ||
const Notification_1 = require("./Notification"); | ||
const NotificationIOS_1 = require("./NotificationIOS"); | ||
const NotificationAndroid_1 = require("./NotificationAndroid"); | ||
const react_native_1 = require("react-native"); | ||
class NotificationFactory { | ||
fromPayload(payload) { | ||
if (react_native_1.Platform.OS === 'ios') { | ||
return payload.aps ? new NotificationIOS_1.NotificationIOS(payload) : new Notification_1.Notification(payload); | ||
} | ||
else { | ||
return new NotificationAndroid_1.NotificationAndroid(payload); | ||
} | ||
} | ||
} | ||
exports.NotificationFactory = NotificationFactory; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Notification } from './Notification'; | ||
export declare class NotificationIOS extends Notification { | ||
identifier: string; | ||
constructor(payload: object); | ||
get aps(): any; | ||
get alert(): any; | ||
get title(): string; | ||
get body(): string; | ||
get sound(): string; | ||
get badge(): number; | ||
get thread(): string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.NotificationIOS = void 0; | ||
const Notification_1 = require("./Notification"); | ||
const _ = require("lodash"); | ||
class NotificationIOS extends Notification_1.Notification { | ||
constructor(payload) { | ||
super(payload); | ||
this.identifier = this.payload.identifier; | ||
} | ||
get aps() { | ||
return this.payload.aps || {}; | ||
} | ||
get alert() { | ||
if (_.isObject(this.aps.alert)) { | ||
return this.aps.alert; | ||
} | ||
else if (_.isString(this.aps.alert)) { | ||
return { | ||
body: this.aps.alert | ||
}; | ||
} | ||
} | ||
get title() { | ||
return this.alert.title; | ||
} | ||
get body() { | ||
return this.alert.body; | ||
} | ||
get sound() { | ||
return this.aps.sound; | ||
} | ||
get badge() { | ||
return this.aps.badge; | ||
} | ||
get thread() { | ||
return this.aps.thread; | ||
} | ||
} | ||
exports.NotificationIOS = NotificationIOS; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const NotificationIOS_1 = require("./NotificationIOS"); | ||
describe('Notification', () => { | ||
it('Should create notification with payload', () => { | ||
const payload = { p: 'p' }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.payload).toEqual(payload); | ||
}); | ||
it('Should create notification with valid aps', () => { | ||
const aps = { alert: {} }; | ||
const payload = { aps }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.aps).toEqual(aps); | ||
}); | ||
it('Should create notification with empy aps', () => { | ||
const payload = { aps: undefined }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.aps).toEqual({}); | ||
}); | ||
it('Should return alert object', () => { | ||
const payload = { aps: { alert: { title: 'title' } } }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.alert).toEqual(payload.aps.alert); | ||
}); | ||
it('Should return alert object when alert is string', () => { | ||
const payload = { aps: { alert: 'title' } }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.alert).toEqual({ | ||
body: 'title' | ||
}); | ||
}); | ||
it('Should return title from alert', () => { | ||
const payload = { aps: { alert: { title: 'title' } } }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.title).toEqual('title'); | ||
}); | ||
it('Should return body from alert', () => { | ||
const payload = { aps: { alert: { title: 'title', body: 'body' } } }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.body).toEqual('body'); | ||
}); | ||
it('Should return badge from aps', () => { | ||
const payload = { aps: { badge: 0 } }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.badge).toEqual(0); | ||
}); | ||
it('Should return sound from aps', () => { | ||
const payload = { aps: { sound: 'sound.wav' } }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.sound).toEqual('sound.wav'); | ||
}); | ||
it('Should return thread from aps', () => { | ||
const payload = { aps: { thread: 'thread' } }; | ||
const notification = new NotificationIOS_1.NotificationIOS(payload); | ||
expect(notification.thread).toEqual('thread'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { EventsRegistry } from './events/EventsRegistry'; | ||
import { Notification } from './DTO/Notification'; | ||
import { NotificationCategory } from './interfaces/NotificationCategory'; | ||
import { NotificationChannel } from './interfaces/NotificationChannel'; | ||
import { NotificationsIOS } from './NotificationsIOS'; | ||
import { NotificationsAndroid } from './NotificationsAndroid'; | ||
import { NotificationPermissionOptions } from './interfaces/NotificationPermissions'; | ||
export declare class NotificationsRoot { | ||
readonly _ios: NotificationsIOS; | ||
readonly _android: NotificationsAndroid; | ||
private readonly notificationFactory; | ||
private readonly nativeEventsReceiver; | ||
private readonly nativeCommandsSender; | ||
private readonly commands; | ||
private readonly eventsRegistry; | ||
private readonly eventsRegistryIOS; | ||
private readonly uniqueIdProvider; | ||
private readonly completionCallbackWrapper; | ||
constructor(); | ||
/** | ||
* registerRemoteNotifications | ||
*/ | ||
registerRemoteNotifications(options?: NotificationPermissionOptions): void; | ||
/** | ||
* postLocalNotification | ||
*/ | ||
postLocalNotification(notification: Notification, id?: number): number; | ||
/** | ||
* getInitialNotification | ||
*/ | ||
getInitialNotification(): Promise<Notification | undefined>; | ||
/** | ||
* setCategories | ||
*/ | ||
setCategories(categories: [NotificationCategory?]): void; | ||
/** | ||
* cancelLocalNotification | ||
*/ | ||
cancelLocalNotification(notificationId: number): void; | ||
/** | ||
* removeAllDeliveredNotifications | ||
*/ | ||
removeAllDeliveredNotifications(): void; | ||
/** | ||
* isRegisteredForRemoteNotifications | ||
*/ | ||
isRegisteredForRemoteNotifications(): Promise<boolean>; | ||
/** | ||
* setNotificationChannel | ||
*/ | ||
setNotificationChannel(notificationChannel: NotificationChannel): void; | ||
/** | ||
* Obtain the events registry instance | ||
*/ | ||
events(): EventsRegistry; | ||
/** | ||
* ios/android getters | ||
*/ | ||
get ios(): NotificationsIOS; | ||
get android(): NotificationsAndroid; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need