#react-native-firebase/messaging how to customize notification? - firebase

According to the documentation: https://rnfirebase.io/messaging/usage I want to display the background notification from firebase but with custom configuration, like a custom icon, custom data, and custom function on tapping on a notification.
// index.js
import { AppRegistry } from 'react-native';
import messaging from '#react-native-firebase/messaging';
import App from './App';
// Register background handler
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Message handled in the background!', remoteMessage);
});
AppRegistry.registerComponent('app', () => App);
How to customize this?

https://github.com/invertase/react-native-firebase/issues/3826#issuecomment-648903659
As per this statement and also referring the doc, react native firebase version 6+ messaging only supports cloud integration and simple notification display.
If you need extra configuration while displaying a notification, you should use any other local notification library like "Notifee"

Related

Next.js withPageAuthRequired with getStaticProps

According documentation #auth0/nextjs-auth0 we can use withPageAuthRequired for trigger login screen on pages required login.
short variant: export const getServerSideProps = withPageAuthRequired();
But what to do if I need to use getStaticProps for pre-render page at build time which can't be used together with getServerSideProps? Is there any way to use withPageAuthRequired on request static generated pages?
Right now I am using double check on client side for check auth. But I would rather use a server side check as i use on other pages.
P.S. There is way to use withPageAuthRequired on client side as well. This is not suitable for my use
Since getStaticProps() is used to build a static page (i.e., no server-side logic/rendering at request time), the auth check and redirect to login will have to happen on the client side.
You might be able to get the behaviour you want by sticking a proxy in front of the static resource (e.g., using Lambda#Edge), though I'm not very familiar with this approach yet.
From your question it sounds like you are already familiar with how to do the check/redirect on the client side, but for the benefit of others who come across this post in the future:
To fetch user information on the client side, add a <UserProvider> to your app, and call the useUser() hook in client-side components.
See docs:
Wrap your pages/_app.js component with the UserProvider component:
// pages/_app.js
import React from 'react';
import { UserProvider } from '#auth0/nextjs-auth0';
export default function App({ Component, pageProps }) {
return (
<UserProvider>
<Component {...pageProps} />
</UserProvider>
);
}
You can now determine if a user is authenticated by checking that the
user object returned by the useUser() hook is defined. You can
also log in or log out your users from the frontend layer of your
Next.js application by redirecting them to the appropriate
automatically-generated route:
// pages/index.js
import { useUser } from '#auth0/nextjs-auth0';
export default function Index() {
const { user, error, isLoading } = useUser();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>{error.message}</div>;
if (user) {
return (
<div>
Welcome {user.name}!
Logout
</div>
);
}
return Login;
}
For other comprehensive examples, see the EXAMPLES.md
document.
An alternative approach that uses withPageAuthRequired() on the client side:
import React from 'react';
import { withPageAuthRequired } from '#auth0/nextjs-auth0';
import Layout from '../components/layout';
export default withPageAuthRequired(function Profile({ user }) {
return (
<Layout>
<h1>Profile</h1>
<h4>Profile</h4>
<pre data-testid="profile">{JSON.stringify(user, null, 2)}</pre>
</Layout>
);
});
Linked from additional examples.

Ionic Firebase analytics custom parameters

In my ionic5 app I am sending events like so
export class Logger extends FirebaseAnalytics{
...
aFunction(tapTarget: string){
const logData = {target: tapTarget};
this.log(EventType.TAP, logData);
}
Based on this
but I do not see the event parameters in my firebase console? I see the events but not the payload that the app is sending... ?
Is there a magic setting on firebase console to see those values?
Or is the code above not working?
You are not supposed to extend FirebaseAnalytics.
You must inject it in your constructor.
import { FirebaseAnalytics } from '#ionic-native/firebase-analytics/ngx';
constructor(private firebaseAnalytics: FirebaseAnalytics) {}
this.firebaseAnalytics.logEvent('event_name', {param: 'value'})
.then((res: any) => console.log(res))
.catch((error: any) => console.error(error));
Make sure the Ionic Native wrapper is installed alongside the Cordova plugin itself.
ionic cordova plugin add cordova-plugin-firebase-analytics
npm install #ionic-native/firebase-analytics

Custom notification on React Native using react-native-firebase

I am implementing push notifications in my application using the react-native-firebase library, but I have a question. I need to mount custom notifications in my app, and assemble them from React without the server sending me Title / Body, I need these notifications with the app in the background and fully closed.
I made the following attempt, but to no avail.
In my index I registered my class
AppRegistry.registerHeadlessTask(
"RNFirebaseBackgroundMessage",
() => bgMessaging
);
In my JS class, I treat the following way
import firebase from "react-native-firebase";
import type { NotificationOpen } from "react-native-firebase";
export default async (notificationOpen: NotificationOpen) => {
if (notificationOpen) {
const notification = new firebase.notifications.Notification()
.setTitle("Android Notification Actions")
.setBody("Action Body")
.setNotificationId("notification-action")
.setSound("default")
.android.setChannelId("notification-action")
.android.setPriority(firebase.notifications.Android.Priority.Max);
// Build an action
const action = new firebase.notifications.Android.Action(
"snooze",
"ic_launcher",
"My Test Action"
);
// This is the important line
action.setShowUserInterface(false);
// Add the action to the notification
notification.android.addAction(action);
// Display the notification
firebase.notifications().displayNotification(notification);
}
return Promise.resolve();
};
But I was not successful. Push notifications sent from firebase with fixed title and body work normally.
Thanks and sorry for my english.
Hi Please try with below,
Change .setNotificationId("notification-action") to .setNotificationId(notificationOpen.notification.notificationId)
Change .android.setChannelId("notification-action") to .android.setChannelId(notificationOpen.notification.android.channelId)

Does Next.js not need browser history when using Redux?

I'm trying to migrate my React app to Next.js. I keep having below error from export const history = createBrowserHistory(); in my configureStore.js.
Invariant Violation: Browser history needs a DOM
configureStore.js
import { createStore, combineReducers, compose, applyMiddleware } from "redux";
import { connectRouter, routerMiddleware } from "connected-react-router";
import { createBrowserHistory } from "history";
import thunk from "redux-thunk";
import user from "./modules/user";
import stores from "./modules/stores";
import info from "./modules/info";
export const history = createBrowserHistory();
const middlewares = [thunk, routerMiddleware(history)];
const reducer = combineReducers({
user,
stores,
info,
router: connectRouter(history)
});
export default function configureStore(preloadedState) {
return createStore(
reducer,
preloadedState,
compose(
applyMiddleware(
...middlewares
)
)
);
}
I've found that many things need to be changed when migrating React to Next.js as Next is a framework which requires its own code architecture as well as the difference between SSR and CSR. When I studied Next.js tutorials, there is a routing section which says that routing is differentiated based on CSR or SSR. Does that mean I cannot use browser history in Next.js? That's what I'm guessting. I'm still confused.
You are right. There is different between SSR and CSR. Next.js use Next Router for routing for CSR and if you need custom SSR, then you should ask for some help from frameworks like express.
By doing the CSR, nextjs will remember browser history and back button works as expected. However if you need to change the route to a very diffrernt route you can use any of these solutions:
import Router from 'next/router';
...
Router .push('/about');
Or
import Link from 'next/link';
...
<Link href="/about"><a>about</a></Link>
and if you need to do some extra work before routing then you should use:
Router.beforePopState(({ url, as, options }) => {...}
Migration would take some time and you need to remember next.js will take over the charge for routing and browser history automatically. Unless you customise it.

How do you snapshot test components with actions from Redux connect?

I want to snapshot test a react component that dispatches a redux action in its componentDidMount() handler. The action is given to the component through Redux's connect().
How should I mock the action?
Right now the action is imported in the component (see Newsfeed.js below). So how would I swap it out for a mock action in my test?
I'm using redux-thunk for my async actions, but that shouldn't matter much.
app/components/Newsfeed.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
// An action that makes an async request to get data
import { loadNewsfeedStories } from '../actions/Newsfeed';
class Newsfeed extends Component {
componentDidMount(){
this.props.loadNewsfeedStories();
}
...
}
export default connect(state => ({
stories: state.newsfeed.stories
}),
{
loadNewsfeedStories
})(Newsfeed)
app/tests/Newsfeed.test.js
import React from 'react';
import { Provider } from 'react-redux';
// This creates a mockStore using my reducers and a saved JSON state.
import { mockStore } from './MockState';
// The component to test
import Newsfeed from '../components/Newsfeed';
test('Newsfeed matches snapshot', () => {
const wrapper = mount(
<Provider store={mockStore}>
<Newsfeed />
</Provider>
);
expect(wrapper).toMatchSnapshot();
});
Possible Solutions
Export the unconnected component, and manually pass in all props & mock actions. Will be a lot of extra coding compared to just using the mockStore & provider. Also we won't be testing the 'connected' component.
Use something like Nock? Seems to intercept HTTP calls, so the ajax requests wouldn't actually go anywhere.
For axios, there is a lib called moxios - https://github.com/mzabriskie/moxios
You could try exporting a different connected component, but with a mocked "mapDispatchToProps" function. This way, no action will get through.
But personally, when testing components. I write a mock reducer, these should not change the state but record all dispatched actions (Jests mock functions are very useful for this). This way, you can also test if the correct action is dispatched when clicking a button,...
It's a bad idea to test the component, redux store, and mock http requests at the same time because unit tests should be small.
Another option would be to avoid executing business logic in componentDidMount.
Instead of writing
componentDidMount(){
this.props.loadNewsfeedStories();
}
You can move this logic to the redux module (depends on libs you use).
If you use only redux-thunk without libraries like saga or redux-logic, you can use this https://github.com/Rezonans/redux-async-connect.
but record all dispatched actions
Redux thunks are hard to test. Your mock dispatcher will receive only an array of functions. And you can't verify if a function was created by loadNewsfeedStories() or by someAnotherThunk().

Resources