I'm trying to log a firebase event when a user is receiving a remote push notification when the app is in the background/killed. My notification displays juste fine but I can't log analytics events.
I have tried initializing my firebase app with firebase.initializeApp(config), not knowing if it was initialized in a headless js task but it didn't seem to make a difference.
In-app events log just fine using the Debug View in the firebase console, as well as the notification_receive one automatically
export default async (message: RemoteMessage) => {
const localNotification = new firebase.notifications.Notification()
// setting notification props
const displayNotification = await firebase.notifications().displayNotification(localNotification);
firebase.analytics().logEvent('notification_test', { test: 'test123' }); // this doesn't work
return Promise.resolve(displayNotification);
};
Is there a way to log an event here?
Also, any information on how Headless js works (besides official doc that I've already read of course) would be appreciated.
Thank you!
Related
I have tried to follow this guide https://rnfirebase.io/messaging/usage/ios-setup to set up push notifications for my React-Native application. In particular, I have done the following:
Adding Push Notification & Background Mode capabilities(with Remote fetch and background activities)
Register a key(with APNs enabled) in Apple developer account and upload it to firebase console settings with the correct KeyID(obtained when registering the key) and TeamID(obtained from developer's membership detail)
Register the App Identifier(with APNs capability). Since there are two bundle Identifiers for my project - org.reactjs.native.example.AppName and org.test.AppName, I have tried both but none works.
Register a Provisioning profile. I believe this wil automatically sync with my Xcode.
I note that I can further configure the APNs capability after registering the App Identifier, but this is not mentioned in the guide and I didn't do that:
To configure push notifications for this App ID, a Client SSL Certificate that allows your notification server to connect to the Apple Push Notification Service is required. Each App ID requires its own Client SSL Certificate. Manage and generate your certificates below.
In my React-Native application, I have the following code:
const App => {
useEffect(() => {
async function requestUserPermission() {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
console.log('Authorization status:', authStatus);
}
}
requestPermission();
});
useEffect(() => {
async function getToken() {
await messaging().registerDeviceForRemoteMessages();
const token = await messaging().getToken();
console.log(token);
}
getToken();
});
...
}
After accepting the notification permission request when the app launch. This will output the FCMs token, which I use to send a test message in the Firebase console.
Did I miss any steps? Is it possible to send push notifications in React-Native debug built running under metro in the first place? Thank you in advance.
I figured out the problem. It is because I used a different bundle ID when building the product in XCode and when registering the identifier in Apple Developer Account. The steps by steps does work as of writing.
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')
})
I have an electron app that will just wrap a remote page while adding some extra features. With the following code the page loads and works. When the remote page fires some notifications using the notification API those notifications show up when the electron app is minimized. My problem is that when clicking on those notifications the app does not get put to front like it does when opening the remote page on any other browser directly. I could test this only for Ubuntu 19.10 Linux (Gnome 3).
Any idea if I need to configure something for that or if this is a bug with Electron/Ubuntu/Gnome?
const {app, shell, BrowserWindow} = require('electron');
let mainWindow;
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1024,
height: 786,
});
mainWindow.setMenu(null);
mainWindow.setTitle('My app – Connecting…');
mainWindow.loadURL('https://some.url.somwhere');
// Emitted when the window is closed.
mainWindow.on('closed', () => {
mainWindow = null
})
}
app.on('ready', createWindow);
First of it is NOT a good idea to wrap a remote page unless you really know what you are doing as if you were redirected to a malicious page the page would have access to run code in the operating system. I would suggest giving this a read to make sure you're being safe.
Secondly the notification HTML5 API (runs in renderer) and notification module (runs in main) both do not have default behaviour to bring the page to the front when the notification is clicked you must add this behaviour yourself.
Because your loading a remote page you're probably using the notification module therefore it would be accomplished like follows:
notification = new Notification({title: "Message from: "+result[i].messageFrom,body: messagebody,icon: path.join(__dirname, 'assets','images','icon.png')})
notification.show()
notification.on('click', (event, arg)=>{
mainWindow.moveTop()
mainWindow.focus()
})
I am creating a React-Native app that fetches data from an API as a background service.
I have looked around the web if I can manually rehydrate the store with the data fetched during the background task, but I could not find anything.
Is it possible to rehydrate the redux-persist store manually while the app is killed, from a background 'service' task?
For the people still wondering, if it is possible to use react-native-background-fetch for scheduling ANY task, it is completely fine as long as it does not touch the UI eg. (AsyncStorage, Redux-Persist, Realm, DB...) is not directly related to invoking change in the UI, so it is completely fine to use.
In my particular case, I am using the slowest option - AsyncStorage - to persist a props sort of object which I use on global App level and pass derived data onto my components:
// Example of HeadlessTask implementation
import BackgroundFetch from 'react-native-background-fetch'
import AsyncStorage from '#react-native-community/async-storage';
const HeadlessTask = async () => {
// Prepare data - fetching from API, other transformations...
let propsObject = {};
AsyncStorage.setItem(ITEM_KEY, JSON.strigify(propsObject))
.then(() => {
console.log('[AsyncStorage] Object Saved!');
// For iOS specifically we need to tell when the service job
// is done.
BackgroundFetch.finish();
})
.catch((e) => {
console.log('[AsyncStorage] Error saving object: ', e);
BackgroundFetch.finish();
});
}
P.S. See https://github.com/transistorsoft/react-native-background-fetch to see how to install and implement Background Fetch.
Have seen two different ways to initialize firestore in a react-native app and would like to know what the differences between the two are. The method shown in the firestore docs (https://firebase.google.com/docs/firestore/quickstart#initialize) looks like
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
export fs = admin.firestore();
while the "firebase" way (as seen in this expo post: https://forums.expo.io/t/open-when-an-expo-firebase-firestore-platform/4126/29), which is the way I currently use and appears to work, looks like
import * as firebase from 'firebase';
import 'firebase/firestore';//for using firestore functions, see https://stackoverflow.com/a/50684682/8236733
import { firebaseConfig } from './firebase-credentials';//WARN: gitignored, exports object containing firebase (web)app credentials
// Initialize Firebase
// why in separate file? see https://github.com/zeit/next.js/issues/1999 and https://ilikekillnerds.com/2018/02/solving-issue-firebase-app-named-default-already-exists/
// firebase.initializeApp(firebaseConfig);
try {
firebase.initializeApp(firebaseConfig)
/*WARN:
#firebase/firestore:, Firestore (5.0.4):
The behavior for Date objects stored in Firestore is going to change
AND YOUR APP MAY BREAK.
To hide this warning and ensure your app does not break, you need to add the
following code to your app before calling any other Cloud Firestore methods:
const firestore = firebase.firestore();
const settings = {timestampsInSnapshots: true};
firestore.settings(settings);
With this change, timestamps stored in Cloud Firestore will be read back as
Firebase Timestamp objects instead of as system Date objects. So you will also
need to update code expecting a Date to instead expect a Timestamp. For example:
// Old:
const date = snapshot.get('created_at');
// New:
const timestamp = snapshot.get('created_at');
const date = timestamp.toDate();
Please audit all existing usages of Date when you enable the new behavior. In a
future release, the behavior will change to the new behavior, so if you do not
follow these steps, YOUR APP MAY BREAK.
*/
const fsSettings = {/* your settings... */ timestampsInSnapshots: true};
firebase.firestore().settings(fsSettings)
} catch (err) {
// we skip the "already exists" message which is
// not an actual error when we're hot-reloading
if (!/already exists/.test(err.message)) {
console.error('Firebase initialization error', err.stack)
}
}
export const fs = firebase.firestore()
The post linked to is the only instance where I could find someone else doing this, but again it does work for me (can read and write to firestore).
Very new to using firebase/firestore and would like to use the more 'correct' method. Is there any difference between initializing firestore in the app in these separate ways?
Import:
import * as firebase from 'firebase';
import 'firebase/firestore';
Then
const db = firebase.firestore();
https://github.com/invertase/react-native-firebase
This is a JavaScript bridge to the native Firebase SDKs for both iOS and Android therefore Firebase will run on the native thread.
It has a step-by-step instructions for react-native app integration with firebase.
One important thing is that you have to consider about your react-native version and firebase sdk version.
They do the same things though? The first one simply does it by declaring and expo does it by declaring it inline. You can do it however you like, but both of them do the same things