cordova-plugin-fanmeter v4.1.1
Pluggable's Fanmeter Plugin for Cordova/Capacitor/Outsystems apps
The Fanmeter plugin is the one responsible for enabling Fanmeter in any mobile application. It is a simple plug-&-play plugin that makes available a set of methods that can be used to allow users to participate in activations such as the FAN OF THE MATCH or the SUPER FAN.
Fully-automatized vs Manual Fanmeter
There are two possible types of integration. One is fully-automatized and uses a default native view that is launched to your users for them to participate in Fanmeter - it also launches and delivers push notifications as soon as the event starts and finishes. If, on the other hand, you wish to create your own Fanmeter view, you will follow a manual approach.
Fully-automatized Fanmeter: you want everything automated (including a default Fanmeter view). You should also integrate with FCM to handle received notifications that start the event (in summary, you'll need to use the execute, launchFanmeterNotification and, optionally, the launchFanmeterView methods);
Manual Fanmeter: you want to handle the conditions yourself and develop your own view (just start calling the startService, stopService, and isServiceRunning methods).
Pre-Conditions
Meta-Data
For Android, push permission is required so that a notification is shown to the user so that he knows that a foreground service is running. Also, note that the Location permission is needed for the fans to participate in the geo-restricted events. Hence, you need to ask for such permissions.
For iOS, add the Background Modes capability and enable Location Updates. Also, you must open your Info.plist file and add the following code at the bottom:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>location</string>
<string>remote-notification</string>
</array>
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
<key>PreciseLocationRequired</key>
<string>Access to precise location is required during geo-restriced events!</string>
</dict>
<key>NSLocationAlwaysUsageDescription</key>
<string>Location access is required to participate in geo-restricted events!</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location access is required to participate in geo-restricted events!</string>
Note that, for Android only, Fanmeter is required to use a Data Sync foreground service to communicate non-intrusive sensor data with Pluggable's server. Since API 34 of Android, when publishing an app that uses such services, you are required to fill a Policy Declaration where you must justify the need for such services. In Fanmeter's case, when filling such policy, you will be asked the question "What tasks require your app to use the FOREGROUND_SERVICE_DATA_SYNC permission?".
There, you should:
Select the option OTHER in Other tasks;
Provide the following video link:
https://youtu.be/w4d7Pgksok0
Provide the following description:
Fanmeter is an Android SDK, incorporated in this app, that uses a Data Sync foreground service to communicate non-intrusive sensor data with Pluggable's servers, which are used to quantify the engagement of the user in real-time. The foreground service must start as soon as the user opts to participate in the event (so that it can collect and communicate data) and must keep running until the user himself decides to terminate his/her participation.
Push Notifications
Before using this plugin, if you want a fully-automated experience, you should guarantee that your app already integrates with Firebase Cloud Messaging so that your app can receive push notifications.
Unfortunately, there is no official support from Google to Cordova's Firebase. One possible plugin, Cloud Messaging, can be used even though it has a set of issues that require specific attention when implementing it. For capacitor/Outsystems, look for the official firebase plugin. Nonetheless, the integration of Firebase in Cordova can be done as follows:
Create a new Firebase project;
Android Setup - a configuration file must be downloaded and added to the project:
- On the Firebase console, add a new Android application and enter the projects details. The "Android package name" must match the local package name which can be found inside your app's config.xml file;
- Download the
google-services.json
file and place it into the root directory of your Cordova project; - Add a new tag for the Android platform inside your app's config.xml file:
... <platform name="android"> <resource-file src="google-services.json" target="app/google-services.json" /> </platform> ...
- iOS Setup - to allow the iOS app to securely connect to the Firebase project, a configuration file must be downloaded and added to the project:
- On the Firebase console, add a new iOS application and enter your projects details. The "Apple bundle ID" must match your local project bundle ID. The bundle ID can be found within the "General" tab when opening the project with Xcode or in your app's config.xml file;
- Download the
GoogleService-Info.plist
file and place it into the root directory of your Cordova project; - Add a new tag for the iOS platform inside your app's config.xml file:
... <platform name="ios"> <resource-file src="GoogleService-Info.plist" /> </platform> ...
- Additional iOS Setup - iOS requires further configuration before you can start receiving and sending messages through Firebase. For instance:
- You must upload your APNs authentication key to Firebase. If you don't already have an APNs authentication key, make sure to create one in the Apple Developer Member Center;
- Inside your project in the Firebase console, select the gear icon, select Project Settings, and then select the Cloud Messaging tab;
- In APNs authentication key under iOS app configuration, click the Upload button.
- Browse to the location where you saved your key, select it, and click Open. Add the key ID for the key (available in the Apple Developer Member Center;) and click Upload.
- For further notes, you can check React-Native iOS with Firebase Cloud Messaging, which is quite illustrative.
NOTE: FCM via APNs does not work on iOS Simulators. To receive messages & notifications a real device is required. The same is recommended for Android.
Set up the Fanmeter Plugin in your App
Install the Plugin
You are now ready to use this plugin to properly engage with your fans! To install the Fanmeter Package just run in the root of the project:
cordova plugin add cordova-plugin-fanmeter
Note that for Android, to customize the used notification icon just add the desired icon in the Android's drawable folder and name it ic_push_app_icon. Otherwise, a default icon, not related to your app, will be used.
Method initialize and getEventData
The Entrypoint.initialize()
method is mandatory for both fully-automatized and manual scenarios. It is responsible for initializing the SDK and must be invoked before using any other method (a possible approach is to invoke it in the main app process).
let COMPANY_NAME = 'your_company_name';
let COMPANY_KEY = 'your_company_key';
let EXTERNAL_USER_ID = 'your_user_id';
let EXTERNAL_TOKEN_ID = 'the_id_of_the_device';
let EXTERNAL_USER_EMAIL = 'email@domain.com';
let FCM_TOKEN = 'the_fcm_token';
let TICKET_NUMBER = 't-1234';
let TICKET_STAND = null;
let REGULATION_URL = null;
let NOTIFICATION_CLASS_RESPONSE = null;
let FANMETER_LOG = false;
// When the Fanmeter SDK is initialized, it initializes all company and user data.
cordova.plugins.FanmeterPlugin.initialize(
COMPANY_NAME,
COMPANY_KEY,
EXTERNAL_USER_ID,
EXTERNAL_TOKEN_ID,
EXTERNAL_USER_EMAIL,
FCM_TOKEN,
TICKET_NUMBER,
TICKET_STAND,
REGULATION_URL,
FANMETER_LOG,
function(response){
console.log("JS | SUCCESS initialize | " + JSON.stringify(response));
}, function(error){
console.log("JS | ERROR initialize | " + JSON.stringify(error));
}
);
Where:
- COMPANY_NAME, is the name of your company in Fanmeter;
- COMPANY_KEY, your company's license key;
- EXTERNAL_USER_ID, the user identifier in your db (can be the username, the uuid, ...);
- EXTERNAL_TOKEN_ID, the individual smartphone identifier (allows for the same account in different devices);
- EXTERNAL_USER_EMAIL, the user's email. Nullable;
- FCM_TOKEN, the FCM token id of the user. Nullable;
- TICKET_NUMBER, the user's ticket number - used for additional analytics. Nullable;
- TICKET_STAND, the stand where the user is - used for additional analytics. Nullable;
- REGULATION_URL, the URL to the regulation for your events. Nullable;
- FANMETER_LOG, enables additional logging.
An additional method exists, called getEventData
, being used to obtain the full data of a particular Fanmeter event, in a dictionary, including the defined rewards and leaderboard classifications, if existing. If null, or not provided, this returns the closest event to date:
// You should manage the events to get their name programmatically instead of an hardcoded string.
// If null, will return the closest event to date.
let EVENT_NAME = "Round 1 2024-2025"
// After initialized, you will be able to use the SDK methods.
cordova.plugins.FanmeterPlugin.getEventData(
eventTitle,
function(response) {
console.log("JS | SUCCESS getEventData | ", response);
},
function(error) {
console.log("JS | ERROR getEventData | ", error);
}
);
// OR.
cordova.plugins.FanmeterPlugin.getEventData(
null,
function(response) {
console.log("JS | SUCCESS getEventData | ", response);
},
function(error) {
console.log("JS | ERROR getEventData | ", error);
}
);
Fully-automated Fanmeter
After initializing the Plugin, you are now ready to start calling Fanmeter. In particular, if you want to automate the entire process, this library exposes three methods, that must be called as demonstrated below. In particular:
execute
, launches the SDK Fanmeter default's view as soon as a notification is clicked by the user;launchFanmeterNotification
, launches a local notification to the user, which is required by Android when the app is in the foreground;launchFanmeterView
, launches the SDK Fanmeter default's view. It can be associated with a button or banner in your app, redirecting the user to the Fanmeter native view, allowing users without notification permissions to participate in the event. It will open the Fanmeter view with the event with the closest date to the current date.
The execute
method is used for backgrounded processes and will open the default Fanmeter view to the user. On the other hand, the launchFanmeterNotification
method launches a local notification when the Android app is in a foreground state. An example is as follows, used in your .js files as demonstrated in the next lines.
// Register the background handler and notification tap.
// Using, as example, the firebase.messaging plugin.
cordova.plugins.firebase.messaging.onBackgroundMessage(function(notificationData) {
cordova.plugins.FanmeterPlugin.execute(
notificationData,
NOTIFICATION_CLASS_RESPONSE,
function(response){
console.log("JS | SUCCESS execute | " + JSON.stringify(response));
}, function(error){
console.log("JS | ERROR execute | " + JSON.stringify(error));
}
);
});
// Register the foreground handler.
// Using, as example, the firebase.messaging plugin.
cordova.plugins.firebase.messaging.onMessage(function(notificationData) {
cordova.plugins.FanmeterPlugin.launchFanmeterNotification(
notificationData,
NOTIFICATION_CLASS_RESPONSE,
function(response){
console.log("JS | SUCCESS notificationData | " + JSON.stringify(response));
}, function(error){
console.log("JS | ERROR notificationData | " + JSON.stringify(error));
}
);
});
Where:
- notificationData, is the remote data received with the notification;
- NOTIFICATION_CLASS_RESPONSE, the name of the class that is being instantiated when the user clicks the notification - example: "com.company.activities.SearchActivity" (null opens the app's default view).
Finally, the launchFanmeterView
method should be called on a button click, redirecting users to Fanmeter's default view. This method accepts an eventId, that should be obtained using the getEventData
method. If a null eventId is passed, this method will open the closest available event to the current date.
cordova.plugins.FanmeterPlugin.launchFanmeterView(
eventId,
function(response){
console.log("JS | SUCCESS launchView | " + response);
}, function(error){
console.log("JS | ERROR launchView | " + error);
}
);
// OR.
cordova.plugins.FanmeterPlugin.launchFanmeterView(
null,
function(response){
console.log("JS | SUCCESS launchView | " + response);
}, function(error){
console.log("JS | ERROR launchView | " + error);
}
);
Where:
- eventId, is the event id to show (nullable).
These functions return the following values:
- 1, success;
- -80, no GPS/PUSH permissions;
- -81, GPS disabled;
- -82, invalid event coordinates;
- -89, SDK not initialized;
- -91, invalid notification data;
- -92, invalid company license;
- -93, invalid event;
- -94, event not happening now;;
- -95, invalid external user data;
- -96, failed to get event data;
- -97, failed to start the Fanmeter service;
You are also required to subscribe the user to a FCM topic so that he/she can receive event notifications. This can be done, for example, as follows:
// Get user's FCM token.
// Using, as example, the firebase.messaging plugin.
cordova.plugins.firebase.messaging.getToken().then(function(token) {
// Get the token each time the application loads.
FCM_TOKEN = token
});
// Subscribe to specific topic.
// Using, as example, the firebase.messaging plugin.
cordova.plugins.firebase.messaging.subscribe("football_senior");
Manual Fanmeter
If you want full control and implement your own UI, this library exposes three methods, that must be called as demonstrated below. In particular:
startService
, starts the Fanmeter service that enables Fanmeter for your client's device during a particular event;stopService
, stops the Fanmeter service. The service will, still, terminate automatically as soon as the event ends. This returns 1, if success, otherwise an error code;isServiceRunning
, used to check the current status of the Fanmeter service. Returns 1, if the service is running, otherwise 0.
The startService
method is used to start the Fanmeter service. This method accepts an eventId, that should be obtained using the getEventData
method and should be called as follows (associated, for example, to a particular button):
// You can obtain the eventId of an event by calling the getEventData method.
cordova.plugins.FanmeterPlugin.startService(
eventId,
NOTIFICATION_CLASS_RESPONSE,
function(response){
console.log("JS | SUCCESS startService | " + JSON.stringify(response));
}, function(error){
console.log("JS | ERROR startService | " + JSON.stringify(error));
});
Where:
- event_id, the id of the event the user will participate when the start service is called;
- NOTIFICATION_CLASS_RESPONSE, the name of the class that is being instantiated when the user clicks the notification - example: "com.company.activities.SearchActivity" (null opens the app's default view).
This method returns the following values:
- 1, success;
- -80, no GPS/PUSH permissions;
- -81, GPS disabled;
- -82, invalid event coordinates;
- -89, SDK not initialized;
- -91, invalid notification data;
- -92, invalid company license;
- -93, invalid event;
- -94, event not happening now;;
- -95, invalid external user data;
- -96, failed to get event data;
- -97, failed to start the Fanmeter service;
The stopService
method is used to stop the Fanmeter service (can be toggled with the previous method). Even if the user does not explicitly stop the service, it will automatically stop as soon as the event finishes. This returns 1, if success, otherwise an error code.
cordova.plugins.FanmeterPlugin.stopService(
function(response){
console.log("JS | SUCCESS stopService | " + JSON.stringify(response));
}, function(error){
console.log("JS | ERROR stopService | " + JSON.stringify(error));
}
);
Finally, the isServiceRunning
method is used to check the current status of the Fanmeter service. This returns 1, if the service is running, otherwise 0.
cordova.plugins.FanmeterPlugin.isServiceRunning(
function(response){
console.log("JS | SUCCESS isServiceRunning | " + JSON.stringify(response));
}, function(error){
console.log("JS | ERROR isServiceRunning | " + JSON.stringify(error));
}
);
Additional info
Other important methods are to request user permission to be able to send notifications and request GPS permission. Also, get the user token and listen for changes to get the user FCM_TOKEN and update it when it changes.
// Request push permission.
cordova.plugins.firebase.messaging.requestPermission({forceShow: true}).then(function() {
console.log("Push messaging is allowed");
});
// Get user's FCM token.
cordova.plugins.firebase.messaging.getToken().then(function(token) {
FCM_TOKEN = token
});
If your platform app (iOS and/or Android) is unable to get the new plugin, then, between steps 1. and 2., you'll probably need to relink the platform data:
# Android apps
cordova platform remove android
cordova platform add android
# iOS apps
cordova platform remove ios
cordova platform add ios
For full compatibility, attention to the used versions of XCODE, SWIFT and COCOAPODS. Recommended versions are XCODE=15, SWIFT=5.9, and COCOAPODS=1.14.2. For more info visit https://pluggableai.xyz/ or give us feedback to info@pluggableai.xyz.
5 months ago
5 months ago
6 months ago
6 months ago
6 months ago
11 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago