-
Notifications
You must be signed in to change notification settings - Fork 8
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
Expo Support #166
Comments
Thanks for the feedback and the code you provided. We will take this as a feature request on our end. Unfortunately, we don't have a timeline on this but will keep this issue open and update it whenever we have something to share on this topic. |
A heads up regarding my solution: it breaks the default deep link handling from Expo (when app is terminated). |
Hey giorgiofellipe, unfortunately we have set commitments to improve SDKs across the board that at this point we can't help with your request. However, as I mentioned earlier, we do have this as a feature request on our end and will update this thread as and when we have updates to share. Thanks! |
Hi Giorgio! Does your project use Expo's managed workflow? Our does, and we're also looking into using this library, so I'm trying to figure out if it will be feasible. Thanks! |
@jakemadash yes, we are currently using managed workflow. |
Thanks for this PR @giorgiofellipe! RNs direction is really towards using frameworks now, especially Expo. But most library providers have yet to transition |
Hi @ajaysubra I was wondering if there's any update on Expo support? I'd love to use this in my Expo project. |
Using expo-notifications with Klaviyo it does work as intended, even Push Open events. (only tested on iOS) Install the Klaviyo SDK in your Expo project with: npx expo install klaviyo-react-native-sdk Then, use the following hook to handle push notifications with the Expo Notifications API. This hook listens for notification responses and triggers the import { useEffect } from "react";
import * as Notifications from "expo-notifications";
import { Klaviyo } from "klaviyo-react-native-sdk";
export function useNotificationObserver() {
useEffect(() => {
let isMounted = true;
async function handleNotification(notification: Notifications.Notification) {
if (notification.request.trigger.type === "push") {
const event = {
name: "$opened_push",
properties: notification.request.trigger.payload as Record<string, object>,
};
Klaviyo.createEvent(event);
}
// Optionally, clear the last notification response if needed
// await Notifications.clearLastNotificationResponseAsync();
}
// Check for the last notification response on component mount
Notifications.getLastNotificationResponseAsync().then((response) => {
if (isMounted && response?.notification) {
handleNotification(response.notification);
}
});
// Subscribe to future notification responses
const subscription = Notifications.addNotificationResponseReceivedListener(
(response) => handleNotification(response.notification)
);
return () => {
isMounted = false;
subscription.remove();
};
}, []);
} Explanation
Optional: Uncomment This setup should ensure that your app tracks opened push notifications accurately with Klaviyo. |
@joshmohrer sorry for the late response, I was away from work for a bit. Unfortunately no real updates at this point, other than it's on our near term road map and I that can keep this thread updated as and when we have more clear timelines. Thanks for all your patience. |
Hi I'm also working on getting Push working with Expo and without modify the android or ios folder. I was able to get and push the Token with expo-notifications import * as Notifications from "expo-notifications";
...
Klaviyo.initialize("XXXYYY");
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== "granted") {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== "granted") {
console.error("Failed to get push token for push notification!");
return;
}
const deviceToken = await Notifications.getDevicePushTokenAsync();
console.log(deviceToken?.data);
if (deviceToken != null && deviceToken.data.length > 0) {
Klaviyo.setPushToken(deviceToken.data);
} With that I can get Pushes on iOS and Android (you need to add the To handle the Android
iOS
But no success getting opened events in the campaigns. Any help is welcome. |
@pinguin999 This is what has been working for us on both android and ios, using expo-notifications without needing to add any modules. Also does deep-linking via import * as Notifications from "expo-notifications";
import { router } from "expo-router";
import { Klaviyo } from "klaviyo-react-native-sdk";
import { useEffect } from "react";
import { Platform } from "react-native";
export function useNotificationObserver() {
useEffect(() => {
let isMounted = true;
async function redirect(notification: Notifications.Notification) {
if (notification.request.trigger.type === "push") {
const properties = (
Platform.OS === "ios"
? notification.request.trigger.payload
: Object.fromEntries(
Object.entries(notification.request.content.data).map(
([key, value]) => [key.replace(/^com\.klaviyo\./, ""), value],
),
)
) as Record<string, object>;
if (properties) {
const event = {
name: "$opened_push",
properties,
};
Klaviyo.createEvent(event);
await Notifications.setBadgeCountAsync(0);
await Notifications.clearLastNotificationResponseAsync();
console.log("Notification opened", notification, event);
}
const url =
Platform.OS === "ios"
? notification.request.trigger.payload?.url
: notification.request.trigger.remoteMessage?.data?.url ||
notification.request.content.data["com.klaviyo.url"] ||
notification.request.content.data["url"];
if (url) {
console.log("Redirecting to", url);
router.push(url);
}
}
}
Notifications.getLastNotificationResponseAsync().then((response) => {
console.log("Last notification response", response);
if (!isMounted || !response?.notification) {
return;
}
redirect(response.notification);
});
const subscriptionOpened =
Notifications.addNotificationResponseReceivedListener((response) => {
console.log("Notification response received", response);
redirect(response.notification);
});
const subscription = Notifications.addNotificationReceivedListener((_) => {
Notifications.setBadgeCountAsync(0);
});
return () => {
isMounted = false;
subscription.remove();
subscriptionOpened.remove();
};
}, []);
} |
Thanks @YYODHH your code works great. Small update. My native code can work as well. BUT never test with the email: '[email protected]', from the docs!!! All events with @example.com are filtered out and it will NEVER WORK! |
Thanks for pointing out that oversight @pinguin999, we'll update the example data in the readme! |
@pinguin999 @YYODHH @evan-masseau Ditto for us, got the Klaviyo SDK receiving push notifications in an Expo dev client workflow. Assuming you've done the following (few gotchas that might catch people out with expo-notifications):
You should be able to then request PN permissions in your Expo app and add handlers for receiving Klaviyo PNs. @YYODHH has good code there with deep linking support but here's our very contrived minimum reproducible example: import { useEffect } from "react"
import { Platform } from "react-native"
import * as Notifications from "expo-notifications"
import { Klaviyo } from "klaviyo-react-native-sdk"
Klaviyo.initialize("<PUBLIC API KEY>")
export default function App() {
useEffect(() => {
Notifications.requestPermissionsAsync()
.then(result => {
console.log("Notification permissions", result)
if (result.status !== "granted") {
console.error("Push notification permissions not granted")
return
}
// Nab the device FCM/APNs token, different from your expo push token in the form: "ExponentPushToken[<guid>]"
Notifications.getDevicePushTokenAsync().then((result) => {
console.log(`DEVICE ${Platform.OS === "android" ? "FCM" : "APNs"} PUSH TOKEN`, result)
Klaviyo.setPushToken(result.data)
})
.catch(e => {
console.error(`Error getting device FCM/APNs push token, Klaviyo likely won't have its push token set - Klaviyo PNs will not be receieved!`, e)
})
})
.catch(e => {
console.error("Error getting push notification permissions", e)
})
const subscription = Notifications.addNotificationReceivedListener(notification => {
console.log("Received push notification:", notification)
})
return () => {
subscription.remove()
}
}, [])
return null
} *Note: The problem with having @react-native-firebase/messaging as a direct dependency exists when using only expo-notifications too, i.e - without the Klaviyo SDK in the mix as well. You won't need to import the RN messaging module to set up Klaviyo for Expo, bare bones at least. Things will compile and build fine, the JS side of stuff will run okay too but you'll never receive notifications. Don't think it's a bug necessarily but just how the build pipeline in Expo works overriding a listener, config etc. |
Checklist
Description
Proposed Solution
That said, we've been recently implementing it in an Expo project and I'll share the plugin files needed to implement at least Push Open event (it may be extended to other features).
Maybe it clears the path for some people who are planning to use it and make maintainers realize it is not that difficult to add out-of-the-box Expo support.
withKlaviyo.js
withKlaviyoIOS.js
withKlaviyoAndroid.js
It may need some tweaking.
The text was updated successfully, but these errors were encountered: