Skip to content

Commit 717f6b4

Browse files
Merge pull request #20 from ravenappdev/feature/react-push-sdk
firebase topic
2 parents dd598a4 + 750ad7d commit 717f6b4

File tree

1 file changed

+139
-44
lines changed

1 file changed

+139
-44
lines changed

docs/push/client-sdk/react-js.mdx

Lines changed: 139 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,27 @@ description: "Raven React SDK lets you receive and manage push notifications in
77

88
### Step 1. Install Raven SDK
99

10-
Run the following commands your project root directory.
10+
Run the following commands your project root directory. Latest version is 1.0.3
1111

1212
```bash
1313
npm i @ravenapp/raven-web-react-sdk
1414
```
1515

1616
### Step 2. Initialize Firebase
1717

18-
##### A. Initialize Firebase on App start/launch. You can get the FIREBASE_CONFIG object and FIREBASE_VAPID_KEY from the Firebase console.
18+
Firebase will get installed as part of Step 1 and you only need to initialize Firebase on App start/launch.
19+
You can get the FIREBASE_CONFIG object and FIREBASE_VAPID_KEY from the Firebase console.
1920

2021
```javascript
2122
import { initFirebase } from "@ravenapp/raven-web-react-sdk";
2223

2324
initFirebase(FIREBASE_CONFIG, FIREBASE_VAPID_KEY);
2425
```
2526

26-
### Step 3. Setup push notifications
27+
### Step 3. Setup Push notifications
2728

28-
1. Add the service worker to your public folder and name it as `messaging-sw.js`. You can place it under your own path in the public folder. Just replcae the FIREBASE_CONFIG object with the one retrieved from Firebase.
29+
1. Add the service worker to your public folder and name it as `messaging-sw.js`. You can place it under your own path in the public folder.
30+
Just replcae the FIREBASE_CONFIG object with the one retrieved from Firebase and RAVEN_APP_ID with your App Id on Raven console.
2931

3032
```javascript
3133
importScripts("https://www.gstatic.com/firebasejs/8.2.9/firebase-app.js");
@@ -35,61 +37,130 @@ importScripts("https://www.gstatic.com/firebasejs/8.2.9/firebase-messaging.js");
3537
// your app's Firebase config object.
3638
// https://firebase.google.com/docs/web/setup#config-object
3739

38-
const FIREBASE_CONFIG = {};
40+
const FIREBASE_CONFIG = YOUR_FIREBASE_CONFIG_OBJECT;
41+
42+
const RAVEN_APP_ID = YOUR_RAVEN_APP_ID;
3943

4044
firebase.initializeApp(FIREBASE_CONFIG);
4145

4246
const messaging = firebase.messaging();
4347

44-
const broadcast = new BroadcastChannel("display-notification");
45-
4648
messaging.onBackgroundMessage((payload) => {
47-
console.log("[messaging-sw.js] Received background message ", payload);
48-
broadcast.postMessage({
49-
type: "DELIVERED",
50-
data: payload["data"],
51-
});
49+
console.log("[messaging-sw.js] Received background message ");
50+
onMessageReceived(payload);
5251
});
5352

5453
function handleClick(event) {
5554
event.notification.close();
56-
broadcast.postMessage({
57-
type: "CLICKED",
58-
data: event.notification.data,
59-
actions: event.notification.actions,
60-
action: event.action,
61-
});
55+
console.log("[messaging-sw.js] Clicked message");
56+
onMessageClicked(event.notification);
6257
}
6358

6459
self.addEventListener("notificationclick", handleClick);
65-
```
6660

67-
2. Request permission from user and retrieve token using the method `setupPushNotification()`. This method takes 3 arguments:
61+
const broadcast = new BroadcastChannel("display-notification");
62+
broadcast.onmessage = (event) => {
63+
try {
64+
let payload = event.data;
65+
if (payload && payload["type"] === "DELIVERED") {
66+
onMessageReceived(payload);
67+
}
6868

69-
- onError: Callback if there is an error while requesting permission or retrieving token
70-
- onTokenReceived(token): Callback once the token is retrieved. We pass the token if you want to store it on your end.
71-
- serviceWorkerPath: String argument which is the path of the service worker in the public folder
69+
if (payload && payload["type"] === "CLICKED") {
70+
onMessageClicked(payload);
71+
}
72+
} catch (err) {
73+
console.log("Broadcast display-notification error: " + err);
74+
}
75+
};
76+
77+
function updateStatus(notificationId, type) {
78+
if (!notificationId || !type) {
79+
return;
80+
}
81+
82+
var BASE_URL = `https://api.ravenapp.dev/v1/apps/${RAVEN_APP_ID}`;
83+
var SET_DELIVERY_STATUS = `${BASE_URL}/push/status`;
84+
85+
//get user api
86+
fetch(SET_DELIVERY_STATUS, {
87+
method: "POST",
88+
headers: {
89+
"Content-Type": "application/json",
90+
},
91+
body: JSON.stringify({
92+
notification_id: notificationId,
93+
type: type,
94+
timestamp: Date.now(),
95+
current_timestamp: Date.now(),
96+
}),
97+
})
98+
.then((response) => {
99+
if (!response.ok) {
100+
throw new Error("HTTP status " + response.status);
101+
}
102+
})
103+
.then((data) => {
104+
// console.log(data);
105+
})
106+
.catch((error) => {
107+
console.error("Error:", error);
108+
});
109+
}
72110

73-
```javascript
74-
import { setupPushNotification } from "@ravenapp/raven-web-react-sdk";
111+
function renderNotification(reg, payload) {
112+
if (payload && payload["data"]) {
113+
//form action array
114+
var actions = [];
115+
for (var i = 1; i <= 4; i++) {
116+
if (payload["data"]["action" + i]) {
117+
var action = payload["data"]["action" + i];
118+
var title = payload["data"]["title" + i];
119+
var icon = payload["data"]["icon" + i];
120+
actions.push({ action: action, title: title, icon: icon });
121+
}
122+
}
75123

76-
setupPushNotification(
77-
() => console.log("Error setting up push"),
78-
(token) => console.log("Got the token from raven: " + token),
79-
process.env.PUBLIC_URL + "firebase"
80-
);
81-
```
124+
const notificationTitle = payload["data"]["title"];
125+
const notificationOptions = {
126+
body: payload["data"]["body"],
127+
icon: payload["data"]["icon"],
128+
data: payload["data"],
129+
image: payload["data"]["image"],
130+
actions: actions,
131+
};
132+
reg.showNotification(notificationTitle, notificationOptions);
133+
}
134+
}
82135

83-
### Step 4. Initialize Raven
136+
function onMessageReceived(payload) {
137+
renderNotification(self.registration, payload);
138+
setTimeout(() => {
139+
updateStatus(payload["data"]["raven_notification_id"], "DELIVERED");
140+
}, 2000);
141+
}
84142

85-
Raven will get initialized after user login.
143+
function onMessageClicked(payload) {
144+
const clickBroadcast = new BroadcastChannel("click-notification");
145+
var action = payload["action"];
146+
if (!action) {
147+
action = payload["data"]["click_action"];
148+
}
149+
clickBroadcast.postMessage({
150+
click_action: action,
151+
});
152+
setTimeout(() => {
153+
updateStatus(payload["data"]["raven_notification_id"], "CLICKED");
154+
}, 2000);
155+
}
156+
```
157+
158+
### Step 4. <mark> Server Side: </mark> API that returns a unique signature for the user
86159

87-
1. After login once you have the userId of the user, you will need to retrieve a unique signature for the user.
160+
You will need an API on the server side that returns a unique signature for a user.
88161

89-
- This is required to sync user and their push tokens on Raven. This can be done by generating a hash of the
90-
userId signed with the Raven API Key.
91-
- Since this signature requires Raven API key, it is highly recommended to
92-
create a backend API that generates the hash and sends to the frontend.
162+
- This is required to securely identify the user on Raven without exposing the Raven API Key on the client side.
163+
- The client requests from its server a hash of the userId and Raven API key. All subsequent requests from client to Raven will have this signature.
93164
- Following example shows how to generate a **HMAC-SHA256** Signature (hash of
94165
your userId signed with your Raven API Key) in Java -
95166
Add this dependency to `pom.xml` for using **HmacUtils** to generate signature
@@ -110,22 +181,44 @@ private String hmacSha256Signature(String userId, String apiKey) {
110181
}
111182
```
112183

113-
- You can generate the signature on login and pass to the SDK on initialization as shown in the next step.
114184
- For testing purposes, use the free
115185
[HMAC-SHA256 hash generator tool](https://www.devglan.com/online-tools/hmac-sha256-online).
116186
Pass the text as the user identifier and the secret key as your Raven API key.
117187

118-
2. Initialize the SDK after login
188+
### Step 5. Initialize Raven
189+
190+
#### 5.1 Before user logs in
191+
192+
- You need to do this step if you want to send notifications to the user who has not logged in yet.
193+
You will have to use Firebase topics to send notifications which is described in detail in the More section.
194+
195+
- Now you can use the following method to initialize Raven before login.
196+
197+
```javascript
198+
import { initRavenBeforeLogin } from "@ravenapp/raven-web-react-sdk";
199+
200+
initRavenBeforeLogin(RAVEN_APP_ID, tokenHash);
201+
```
202+
203+
- You can get RAVEN_APP_ID from Settings in Raven. tokenHash is generated using the Firebase token.
204+
Use the token from Raven SDK in Step 3.2 and generate a hash of the token with the API created in Step 4.
205+
The idea is to use the Firebase token as a replacement for userId, till the user logs in.
206+
207+
#### 5.2 After user logs in
208+
209+
- Once the user logs in, you need to reinitialize Raven.
210+
211+
- Now you can use the following method to initialize Raven before login.
119212

120213
```javascript
121-
import { initRaven } from "@ravenapp/raven-web-react-sdk";
214+
import { initRavenAfterLogin } from "@ravenapp/raven-web-react-sdk";
122215

123-
initRaven(RAVEN_APP_ID, RAVEN_SECRET_KEY, "USER_ID");
216+
initRavenAfterLogin(RAVEN_APP_ID, userIdHash, userId);
124217
```
125218

126-
- You can get RAVEN_APP_ID from Settings in Raven. RAVEN_SECRETY_KEY is the secret generated in the previous step. The third argument is the userId of the loggedin user.
219+
- You can get RAVEN_APP_ID from Settings in Raven. userIdHash is generated by creating a hash of userId using the API created in Step 4.
127220

128-
### Step 5. Handle notification clicks
221+
### Step 6. Handle notification clicks
129222

130223
Listen to the broadcast channel: `click-notification`. The `clickAction` variable will have the action string which you can use to open a window or take any specific action
131224

@@ -147,6 +240,8 @@ useEffect(() => {
147240
}, []);
148241
```
149242

243+
##
244+
150245
<Check>
151246
You are all set! Just fire Raven API and you should see your web push notification 👍 If you are
152247
facing any issues, please email us on support@ravenapp.dev

0 commit comments

Comments
 (0)