Firebase push conversion event - ios

We have a app with 3 different flavours. We set them up to use firebase notifications with one project per flavour. So 3 apps from the same codebase each one with there own firebase project.
We also added a custom event that we enabled for conversion.
For one of the apps, when sending pushes I can select the custom event to be used as a conversion event with the push, and that works and tracks fine. For the other two I can select the custom event fine but when I try to send the notification I get a error:
"Unable to reserve a user property for Notification conversion funnel analysis for"
Anyone know why this occurs and how to resolve it?

I fixed it by adding a user property to the user properties tab in the analytics section of firebase console. The user property had nothing to do with the actual conversion event but adding at least one user property seems to have initialised something that made the conversion event selectable.

Related

IOS expo push notifications in app killed state

To give more clarity on the issue, i am developing this for IOS using expo push notifications and react-navigation v6 along with expo sdk44 in my current project.
I am having an issue when the user interacts with the notification while the app is in a killed state (the notificatiosn arrives succesfully with all of the data), what im having trouble with is, i want to navigate the user to a specific screen. The problem is because my navigationRef is null. Here i need to mention i did not create a seperate RootNavigator. Like it is shown here https://reactnavigation.org/docs/navigating-without-navigation-prop/ .
What would be the "proper" way of handling this? So far i've tried putting all of the relevant push notification listener code inside NavigatonContainer's onReady callback ( this worked).
I also tried making a seperate useEffect and changing the state of a isReady variable and setting its new value in <NavigationContainer ref={navigationRef} onReady={() => {setNavigatorReady(true)}}> to force a rerender and thus running the code inside useEffect again. (this approach did not work)
Just to sum up my current problem. When the user interacts with a notification while the app is in a killed state i want them to be navigated to a specific screen.
Thanks in advance.
I too am using react-navigation 6.x and expo. To tackle this problem I pretty much followed this section on expo's docs: https://docs.expo.dev/versions/latest/sdk/notifications/#addnotificationresponsereceivedlistenerlistener-event-notificationresponse--void-void.
It shows you how to implement addNotificationResponseReceivedListener which is called whenever a user interacts with a notification. It works in all situations, even when the app is killed, which is the specific situation you are interested in.
The docs also show you how to integrate this listener with react-navigation. Link: https://docs.expo.dev/versions/latest/sdk/notifications/#handling-push-notifications-with-react-navigation

MobileFirst Platform Operational Analytics - Log Screen Visit Times and Custom Crash Details

I'm developing an iOS app using MFP 7.0.
Each screen (i.e., view controller) has a unique ID, and I am supposed to use Operational Analytics to send the following info to the server:
How long the user spent on each screen
On which screen the app crashed
Regarding #1, I guess I am supposed to use WLAnalytics's
- (void) log:(NSString*)message withMetadata:(NSDictionary*)metadata;
(right?)
How can I manage #2? Should I just log the screen ID (using the method above) every time a transition occurs, and expect the last logged id to be passed when the crash log is sent? Or is there any other way to add custom information to crash logs?
Correct you can follow Custom Data, Custom Charts here https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/7.0/moving-production/operational-analytics/
Crash log is detected and sent automatically post crash next time app is started. There is no way to add custom data to that report. Usually the place where the error happen could be deduced form the crash data stack, if this is not sufficient, you can apply the technique you are describing.

How can I distinguish internal from external updates in Firebase

I'm using iOS/Swift with Firebase as my backend.
When the value of a reference change, I get notified, because I'm adding an observer.
What I need is to be able to know when this change was triggered from my local code or from the server.
You can simply add a child to your reference which stores the uid of the user that updated the reference and compare it with the current app user

iCloud + Core Data: First import and user's feeling of loss of data

I've implemented an iPhone application that has around 50k users. Switching from iOS7 to iOS8 a lot of these users have experienced a terrible feeling when they thought that they data get lost.
I've implemented the first-import behaviour that I thought was the one suggested by Apple
1) Users launch the App
2) iCloud, automatically, starts synching data previously stored on iCloud
3) At some point user get notified that data from iCloud is ready thanks to NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted
The problem is with 3) At some point:
Users that have to sync a lot of data need minutes to get the synch completed and in the meanwhile they think that their data is lost.
I really don't know how to let my users know that they have to wait to see their data synched, because I don't know when this operation starts.
I'm thinking about a possible solution:
During the first launch of the App, asking to the user if he wants to use iCloud. If he chooses to use it, building the database with iCloud options, so I know exactly that the synch is starting here (I suppose...)
I'm really not sure about how to implement this behaviour since I've always seen Core Data settings into the AppDelegate but to achieve this behaviour I suppose I need to move all the CoreData settings in a Controller.
What do you think about this solution? how are you working around this problem in you Apps?
Your idea is right, at least it is that what we do. But leave it in the appDelegate.
Differentiate between with iCloud and without iCloud when doing the "addPersistentStoreWithType". If you do it with iCloud options, it will directly start to build the local store which is a kind of a placeholder ( I'm sure you know that, but just to make my thoughts clear). As soon as this is done, the sync starts from iCloud. So this is the starting point I understood you were looking for.
You can watch that process using the notifications by NSPersistentStoreCoordinatorStoresDidChangeNotification and inform you user accordingly triggered by that notification.
If you look at "Reacting to iCloud Events" in the docs https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingSQLiteStoragewithiCloud/UsingSQLiteStoragewithiCloud.html#//apple_ref/doc/uid/TP40013491-CH3-SW5 there is a detailed desc.
To summarize, the event you're describing is part of the account transitions process. An account transition occurs when one of the following four events is triggered:
Initial import
the iCloud account used did change
iCloud is disabled
your application's data is deleted
During this event, Core Data will post the NSPersistentStoreCoordinatorStoresWillChangeNotification and NSPersistentStoreCoordinatorStoresDidChangeNotification notifications to let you know that an account transition is happening. The transition type we're interested in is NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted.
For information, I've moved all Core Data related code to my own Manager for simplicity and use it with a singleton design pattern. While setting up the singleton, I register the Manager for all relevant notifications (NSPersistentStoreDidImportUbiquitousContentChangesNotification, NSPersistentStoreCoordinatorStoresWillChangeNotification, NSPersistentStoreCoordinatorStoresDidChangeNotification, NSPersistentStoreCoordinatorWillRemoveStoreNotification).
I store several informations in my settings (NSUserDefaults or anything) like the last iCloud state (enabled, disabled, unknown), if the initial import is done or not, etc.
What I end up doing was having a prompt (UIAlertController or anything) to get a confirmation if the user wants to use iCloud or not. I have a displayICloudDialogAndForce:completion: method to do that and only do that if my iCloud state setting is unknown or I use the force parameter.
Then, after the user input, I call a setupCoreDataWithICloud: method, the iCloud boolean parameter depending on the user choice. I would then setup my Core Data stack, on the cloud or not according to the iCloud parameter.
If I'm setting up using iCloud, I would check my settings for the value of an iCloud imported key (boolean). If the value is NO, then I'm presenting a new modal to warn the user about the incoming import that could take some time.
I've registered my manager for different notifications and specially NSPersistentStoreCoordinatorStoresDidChangeNotification. In my storeDidChange: callback, I'm checking the transition type and if it's NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted, I'm changing the content of my modal to show the user that the import was successful and removing it a few seconds later, saving in my settings that the initial import is done.
- (void)storeDidChange:(NSNotification *)notification
{
NSPersistentStoreUbiquitousTransitionType transitionType = [notification.userInfo[NSPersistentStoreUbiquitousTransitionTypeKey] integerValue];
if (transitionType == NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted) {
[settings setDefaults:#(YES) forKey:kSettingsICloudImportedKey];
[ICloudModal dismissWithSuccess];
// ...
}
// Do other relevant things...
}

Firebase Analytics events from iOS not showing up

I am testing the new Google-powered Firebase, and have implemented remote notifications and crash reporting. I am, however, having massive problems with getting Analytics to work.
I track events with FIRAnalytics.logEventWithName(...) and save user pproperties with FIRAnalytics.setUserPropertyString(...). However, no matter what I do, no data shows up in the Firebase Analytics Console.
Well, I do receive some events, but those are not sent by me (like first_open and session_start). Also, this data seems to drop in after a very long time.
Furthermore, when I track events and save user data, I receive the following:
Upload task scheduled to be executed in approx. (s): 3102.294599890709
This seems really strange - Firebase waiting almost an hour before trying to send the next batch of data must be a bug, or is it configurable? When I waited that extremely long delay out, data was sent...but does not show up.
Firebase events are batched together and uploaded once every hour in order to prevent excessive battery drain on the devices. On iOS when you background the app before the 1h upload target the events will be dispatched at this time in the background.
You can enable debug logging for iOS (https://firebase.google.com/docs/analytics/ios/events#view_events_in_the_xcode_debug_console) to see when events are uploaded in debug console.
Once the events are uploaded there is delay at about 3h before the data will show up in the Firebase Analytics dashboard. Also the default day range excludes "today" so you only see events from yesterday. You can switch the date picker to include Today if you like to see the latest events.
The main reason to delay/batch data uploading is to save battery. Each time the network is used the device mobile network modem is put in hi power mode and stay in this mode for a while. If network is used regularly it has sever impact on the battery life. By batching the uploads together and delaying the upload the impact on the battery is significantly reduced.
In Swift it should be like:
FIRAnalytics.logEvent(withName: "SignUp", parameters: ["user_id": userid, "user_name": username])
To view this event in Firebase:
Go to Firebase console → Analytics tab
Click on DebugView tab; your Events are shown there
To view this event in Xcode:
In Xcode, select Product → Scheme → EditScheme
Select Run from left Menu
Select Arguments tab
In the Arguments Passed on Launch, add -FIRAnalyticsDebugEnabled
One dash only!!
Note that -FIRAnalyticsDebugEnabled has only ONE dash in front of it.
If you are not receiving events in console, it may be because you are not following naming convention, as I experienced if there is a space in event name it will never show up in the console like following:
mFirebaseAnalytics.logEvent("Add Camera", bundle);
But when you remove the space like following:
mFirebaseAnalytics.logEvent("Add_Camera", bundle);
Now you will see events in console, after approximately 3 hours.
Application will dispatch the data to console in following cases:
1- Data is more than an hours old
2- App goes into the background
You can watch this tutorial for more information:
Getting Started with Firebase Analytics on iOS: Events - Firecasts
Another thing to check is making sure your logging entries in the Arguments Passed on Launch are correct. They should start with a - e.g
-FIRAnalyticsDebugEnabled
and not
FIRAnalyticsDebugEnabled
I wasted an hour the other day wondering why nothing gets logged.
React-Native App (IOS/Android)
I had the same problem, debugView wasn't working, and streamView glitches a few times, the best way ive found to test my events was to logEvents with my createPageEvent() and then
the important thing is to put the app into background after logging the events, they will show up almost in realtime on firebase events or in streamView (check this article to see when events are sent to firebase)
events are only sent after 1 hour since they have been logged or immediately if you put your app in background.
import firebase, { RNFirebase } from 'react-native-firebase';
export default class AnalyticsService {
static async initialize() {
firebase.analytics().setAnalyticsCollectionEnabled(true);
}
static async createPageEvent(screen: string) {
firebase.analytics().setCurrentScreen(screen)
firebase.analytics().logEvent(`open_${screen}`)
}
}
the result is this in streamView almost realtime ->
Now you can start building funnels and stuff
first_open, session_start are listed by Firebase as Automatically collected events.
I can not help you with the extreme upload task delay you encounter on your custom events.. but Firebase Analytics is less than a week old and it may be just a bug on their side.
I found this StackOverflow question which mention the same debug lines but related to Google App Measurement or old Google Mobile Analytics SDK.
Also, be aware that Firebase Console won't show events in real-time (source):
You can view aggregrated statistics about your events in the Firebase console dashboards. These dashboards update periodically throughout the day. For immediate testing, use the logcat output as described in the previous section.
Just a simple note here: according to this little video https://www.youtube.com/watch?v=5pYdTgSkW5E after playing with your simulator you must press the home button on the Xcode, otherwise the data will not be sent to the server.
The most common problem most of the people are facing is the firebase is not logging events even though everything is working perfectly fine
This is what i found in there docs
If you need to deactivate Analytics collection permanently in a version of your app, set FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED to YES in your app's Info.plist file. Setting FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED to YES takes priority over any values for FIREBASE_ANALYTICS_COLLECTION_ENABLED in your app's Info.plist as well as any values set with setAnalyticsCollectionEnabled.
To re-enable collection, remove FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED from your Info.plist. Setting FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED to NO has no effect and results in the same behavior as not having FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED set in your Info.plist file.
So you have to remove FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED from your google-servicesinfo.plist file to make analytics work
Make sure your device is not set to battery save mode. In this mode events may be accumulated and sent only once in a while, even if you run firebase in debug mode as explained by others.
It takes too much time to update events in Firebase. Probably it is done once a day. See iOS or Android logging of Firebase events.
You can enable verbose logging to monitor logging of events by the SDK
to help verify that events are being logged properly. This includes
both automatically and manually logged events.
You can enable verbose logging as follows:
In Xcode, select Product > Scheme > Edit scheme...
Select Run from the left menu.
Select the Arguments tab.
In the Arguments Passed On Launch section, add
-FIRAnalyticsDebugEnabled.
The next time you run your app, your events will display in the Xcode
debug console, helping you immediately verify that events are being
sent.

Resources