How to send session info and do automated page tracking in expo react native segment and amplitude integration - react-native

I am using Segment[expo-analytics-segment] to send tracking info to Amplitude(Configured as the destination in app.segment.com) in an expo react native app. Though I am sending session info(epoch time) - The session always gets registered as -1, hence I am unable to access 'funnel' feature in Amplitude.
Also - How do we enable automatic page tracking in expo segment+amplitude configuration?
This is what I have done so far in App.tsx
Segment.initialize({
androidWriteKey: 'androidKey', // from Segment
iosWriteKey: 'iOsKey', // from segment
});
global.epochInMilliSeconds = Date.now();
Segment.identifyWithTraits(
user.sub,
{ email: 'notgood#gmail.com' },
{
event: 'App Started',
integrations: {
Amplitude: {
sessionId: global.epochInMilliSeconds,
},
},
}
);
Segment.trackWithProperties(
'App Started',
{ email: 'fancyemail#gmail.com' },
{ integrations: { Amplitude: { session_id: global.epochInMilliSeconds } } }
); <------------------- Did not work. Session id is -1**
Segment.track('App Started'); // <-----------------------Session id is -1
More info - https://github.com/expo/expo/issues/10559
I followed this example for the above code sample: https://community.amplitude.com/instrumentation-and-data-management-57/how-do-we-set-session-in-amplitude-while-using-segment-in-cloud-mode-111

Amplitude website mentions that session Ids are not automatically tracked.
https://help.amplitude.com/hc/en-us/articles/217934128-Segment-Amplitude-Integration
In case the link changes, it says:
6. Why do all of my events have a sessionId of -1?
You need to use Segment's client-side bundled integration to have our native SDKs track Session IDs for you.

Related

WalletConnect React Native - No events fired

I'm having a hard time getting WalletConnect 1.7.7 to work on React Native. I want to integrate in a crypto Wallet to handle dapps requests. Their documentation is...lacking. I'm following the "quickstart" in their docs, but listeners never gets fired.
import WalletConnect from "#walletconnect/client";
// Create connector
const connector = new WalletConnect(
{
// Required
uri: "wc:8a5e5bdc-a0e4-47...TJRNmhWJmoxdFo6UDk2WlhaOyQ5N0U=",
// Required
clientMeta: {
description: "WalletConnect Developer App",
url: "https://walletconnect.org",
icons: ["https://walletconnect.org/walletconnect-logo.png"],
name: "WalletConnect",
},
});
connector.on("session_request", (error, payload) => {
if (error) {
throw error;
}
// Handle Session Request
});
But session_request or any other event never get's fired. As per their documents that's all I need. Is there anything else I'm missing or perhaps it's not documented?
The documentation for Wallet Connect is very incomplete and there is very little information on the web. Are you using React Native with Expo? Because there the implementation changes. I don't see any flaws in your code. Test your integration from this website https://example.walletconnect.org/.
Using connect event instead of session_request on walllet connect works for me in react native.
connector.on('connect',(error,payload)=>{
console.log('eventtt',payload)
// Alert.alert('Connected')
})

react-native how to remove persistence on firebase snapshot

I am little confused.
I am listening to firebase snapshot with sample code below
unsubscribe = firebase
.firestore()
.collection('collection')
.doc(id)
.onSnapshot(
function(doc) {
// other code
},
);
This will listen to the collection if there's new item for the specific id.
Then, closing the app will unsubscribe to the snapshot
useEffect(() => {
return () => {
if (unsubscribe) {
unsubscribe()
}
}
}, []);
It is working fine.
However, given the scenario.
If the snapshot triggered (eg. { value: 1 }) and then I closed the app.
Removed the value on the firebase for the specific id. (meaning the id should not received the item)
Re-open the app
I still get the previous value which is { value: 1} and then get the newest value which is undefined (since i removed the value)
Is the value persists on the app? How can I remove this one upon re-opening of the app?
Thanks!
From this answer:
There is now a feature in the API for clearing persistence. It is not recommended for anything but tests, but you can use
firebase.firestore().clearPersistence().catch(error => {
console.error('Could not enable persistence:', error.code);
})
It must run before the Firestore database is used.

Capacitor / Ionic / Vue Local Notification eventlistener

I'm trying to get Local Notifications working in an Ionic Vue app (using capacitor).
I did get scheduling notifications working, but now i want to listen to clicks on the notification.
in main.js I bind LocalNotifications to this.$LocalNotifications:
import { Plugins } from '#capacitor/core';
const { LocalNotifications } = Plugins;
Vue.prototype.$LocalNotifications = LocalNotifications;
in my Root component App I have this:
created() {
console.log('Created!')
document.addEventListener('deviceready', () => {
console.log('ready');
this.$LocalNotifications.addListener('localNotificationReceived', (notification) => {
console.log('Notification action received', notification);
});
}, false);
}
When I build and run on the ios-emulator, i get the following output in my log:
APP ACTIVE
To Native Cordova -> Badge load Badge1248600129 ["options": []]
⚡️ [log] - onscript loading complete
To Native Cordova -> Device getDeviceInfo Device1248600130 ["options": []]
⚡️ To Native -> Storage get 90127150
⚡️ TO JS {"value":null}
⚡️ [log] - Created!
To Native Cordova -> LocalNotification launch LocalNotification1248600131 ["options": []]
To Native Cordova -> LocalNotification ready INVALID ["options": []]
⚡️ To Native -> LocalNotifications addListener ⚡️ [log] - ready
90127151
⚡️ WebView loaded
⚡️ To Native -> App addListener 90127152
When I schedule a Notification, the notification does show up, but I think something doesn't go quite well when i'm adding the listener:
INVALID ["options":[]]
Does anyone have any idea how to solve this?
Or does anyone have a code example of working notifications in an Ionic Vue app?
Kind regards,
Bram
To sum up:
You should use localNotificationActionPerformed instead of localNotificationReceived. The latter is called when notifications are displayed, while the other is listening to actions performed on a notification (as it's stated in the docs), that of course includes clicking / tapping on it.
So your code would look like this:
this.$LocalNotifications.addListener('localNotificationActionPerformed', (notification) => {
console.log('Notification action received', notification.actionId);
});
...which would output "tap". Since you did write 'Notification action received', I assume you wanted to get the action, so I added .actionId after 'notification', which only by itself would be logged as [object Object] or as the object tree.
You also asked for code example, so here it comes:
// 1.
import { LocalNotifications } from '#capacitor/local-notifications';
// 2.
await LocalNotifications.requestPermissions();
// 3.
await LocalNotifications.registerActionTypes({
types: [
{
id: 'your_choice',
actions: [
{
id: 'dismiss',
title: 'Dismiss',
destructive: true
},
{
id: 'open',
title: 'Open app'
},
{
id: 'respond',
title: 'Respond',
input: true
}
]
}
]
});
// 4.
LocalNotifications.schedule({
notifications: [
{
id: 1,
title: 'Sample title',
body: 'Sample body',
actionTypeId: 'your_choice'
}
]
});
// 5.
LocalNotifications.addListener('localNotificationActionPerformed', (notification) => {
console.log(`Notification ${notification.notification.title} was ${notification.actionId}ed.`);
});
1: Since your question, plugins have been placed into their own npm packages, so one needs to install #capacitor/local-notifications and import from there.
2: You should make sure that notifications are allowed, ask for permissions if needed.
3: Tapping was your question's topic, but you can define a lot more than that.
4: This is how you actually create & send a notification at once.
5: Logs "Notification Sample title was taped / opened / dismissed / responded.", according to the given action (but not always according to grammar).
Finally, if someone's just getting into local notifications, check out the really nice documentation on what else (a whole lot more!) can be done and also watching this video might give one a head start. At least that's what I did.

Showing fcm notification message in JSON format when app is killed or in background in react-native-fcm

I am using react-native-fcm library for android device. I am getting notification properly when my application is running, but when my application is in the background or killed then I am getting notification data in JSON format similarly in an image I shared here.
componentDidMount() {
// iOS: show permission prompt for the first call. later just check permission in user settings
// Android: check permission in user settings
FCM.requestPermissions().then(()=>console.log('granted')).catch(()=>console.log('notification permission rejected'));
/*FCM.getFCMToken().then(token => {
console.log('Token',token)
// store fcm token in your server
});*/
this.notificationListener = FCM.on(FCMEvent.Notification, async(notif) => {
console.log('FCM notification', notif)
this.sendRemote(notif)
});
// initial notification contains the notification that launchs the app. If user launchs app by clicking banner, the banner notification info will be here rather than through FCM.on event
// sometimes Android kills activity when app goes to background, and when resume it broadcasts notification before JS is run. You can use FCM.getInitialNotification() to capture those missed events.
// initial notification will be triggered all the time even when open app by icon so send some action identifier when you send notification
/*FCM.getInitialNotification().then(notif => {
console.log('FCM', notif)
this.sendRemote(notif)
//console.log('Initial Notification',notif)
});*/
FCM.getInitialNotification().then((notif: any) => {
// for android/ios app killed state
console.log("ifAny",notif)
if (notif) {
console.log("Any",notif)
// there are two parts of notif. notif.notification contains the notification payload, notif.data contains data payload
}
});
}
sendRemote(notif) {
var data = notif.fcm.body;
var title = notif.fcm.title;
FCM.presentLocalNotification({
title: 'App Name',
body: title,
big_text: title,
large_icon: 'ic_launcher',
priority: 'high',
sound: "default",
click_action: this.clickActions(notif),
show_in_foreground: true,
wake_screen: true,
local: true,
param: notif.notify_about,
paramData: data
});
}
notify_about:'',
fcm:{action:null,
body:"{data:'',time:''}",
color:null,
icon: '',
tag:null,
title:"Notification title"}
this is my data format which I am sending from the server.
Here I want to show only data body. But when the app is killed or in the background, it shows the complete body in the notification.And Its working fine when the app is running.

Multiple realms in React Native don't query realm object server correctly on first launch of app after install

I am having an issue dealing with multiple realms in React Native. I'm working on an app that allows users to use the app without having a subscription (using a local realm) and then at any point in their app journey they have the option of upgrading to a subscription with syncing (which uses sync to a realm object server).
When I start the app I check to see if they are using sync and if so I initialize a synced realm with their user and everything works great. I get all the data I expect.
However, when the app starts on first launch after install (that part about first launch after install is crucial) and I see that they don't use sync I initialize a local realm which I save data to until they decide to log in to their sync account (if they have one). At this point I attempt to pull information from the synced realm but it does not have the information that I saw when I only initialized the synced realm (in the case that on app startup I detect they use sync).
I am able to log in as the sync user but the data isn't there if I've previously initialized a local realm AND this logic gets run on the first launch of the app after install. The data only shows up from the realm object server when I initialize a local and synced realm on a secondary launch of the app (no reinstall before launching).
Here's a simple test script with dummy data in it with which I've been able to replicate the observed behavior:
const username = 'testuser2';
const password = 'supersecret';
const tld = 'REALM_OBJECT_SERVER_TLD';
class Test extends Realm.Object {}
Test.schema = {
name: 'Test',
properties: {
id: {
type: 'string',
},
}
};
function initLocalRealm() {
return new Realm({
path: 'local.realm',
schema: [Test],
});
}
function initSyncedRealmWithUser(user) {
return new Realm({
path: 'synced.realm',
sync: {
user,
url: `realm://${tld}:9080/~/data`,
},
schema: [Test],
});
}
function writeTestObjectWithId(realm, id) {
realm.write(() => {
realm.create('Test', {
id,
});
alert(`Test object with id: ${id}`);
});
}
initLocalRealm();
// setup
// uncomment this and comment out the login section to setup user on first run
// Realm.Sync.User.register(`http://${tld}:9080`, username, password, (error, user) => {
// if (error) {
// return;
// }
// const syncedRealm = initSyncedRealmWithUser(user);
// writeTestObjectWithId(syncedRealm, '1');
// });
// login
Realm.Sync.User.login(`http://${tld}:9080`, username, password, (error, user) => {
if (error) {
return;
}
const syncedRealm = initSyncedRealmWithUser(user);
alert(`Synced realm test objects: ${syncedRealm.objects('Test').length}`);
});
If you create a react native app and then add this code to the main components componentDidMount function you should see that on the first run of the app (after you've uncommented the register code once) you will see the Test collection length at 0, but then when you refresh you will see the Test collection length at 1.
Any help on this would be awesome.
Thanks!
running your code snippet, I get a length of 1 immediately as soon as I uncomment the login section. Could you try observing your synchronized realm with the Realm Browser and see if it seems to have the data you are expecting after registering the user?