how to remove firebase.notifications().onNotificationOpened listener? - reactjs

I am working on a react native project and using react-native-firebase library. Setting up listener is working but I am not able to find a way to remove listener.
I am setting up this listener on homepage so whenever user reach to homepage. Listener get registered multiple times and action multiple times as result.
I want to destroy this listener then again start a new one.
firebase.notifications().onNotificationOpened((notificationOpen) => {
if (notificationOpen) {
const notification: Notification = notificationOpen.notification;
if(notification.data.type){
}
}
});
If anyone can help, that will be appreciated...

You need to call the listener again in order to remove it as mentioned in the docs.
componentDidMount() {
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
//... Your Stuff
}
}
componentWillUnmount() {
this.notificationOpenedListener();
}

Related

Is there a way to get a useEffect cleanup to run when a user closes the webpage?

So for some reason, if I wanted to run a function to update a database when the user leaves a page, I can do that with a useEffect return/cleanup function. But is there a way to do that if they close the page/browser?
useEffect(() => {
return () => {
window.open("https://www.google.com", "_blank");
};
}, []);
I tried testing like so, but never seemed to work. So I am wondering if there is a way to do this.
To get notified when the window is just about to close, use the onbeforeunload event:
useEffect(() => {
const onBeforeUnload = (e) => {
// run your cleanup code here
}
window.addEventListener('beforeunload', onBeforeUnload);
return () => {
window.removeEventListener('beforeunload', onBeforeUnload);
}
}, []);
You are limited in terms of what you can do during this event. If you want, you can prompt the user whether they really want to close the page, which you do like this:
const onBeforeUnload = (e) => {
// Cancel the event
e.preventDefault(); // If you prevent default behavior in Mozilla Firefox prompt will always be shown
// Chrome requires returnValue to be set
e.returnValue = '';
}
This will display an alert-like message, which you cannot customize. Typically you should only do this if the user has done something where they would expect this kind of message. Ie, they've made changes, and those changes havn't been saved, and they'll be annoyed if they lose them. If you're just running cleanup code, you probably don't need to do this.
You cannot redirect them to another page or show a custom alert. Malicious pages would love this: "Ha ha, you tried to leave my page, well i'm routing you back to it instead".

Unable to set up invisible reCAPTCHA verifier for multi-factor authentication in a react app

As per this article, https://cloud.google.com/identity-platform/docs/web/mfa, I am trying to set up invisible reCAPTCHA. However, the callback function does not seem to fire. The idea is that I want the recaptcha to fire off upon a button click and send a code via the callback function but it is not working.
I am trying to activate the recaptcha via the following function linked to a button with the 'code-button" id.
sendCode () {
const recaptchaVerifier = new firebase.auth.RecaptchaVerifier('code-button', {
'size': 'invisible',
'callback': () => {
// reCAPTCHA solved, you can proceed with phoneAuthProvider.verifyPhoneNumber(...).
// onSolvedRecaptcha();
console.log("captcha is working")
}
})
recaptchaVerifier.render()
}
When I press the button to fire off the sendCode function, the callback inside the recaptchaVerifier does not seem to work. It is supposed to console.log "captcha working" but it does not as I check the console.
I do get the following issues in the console but I am not sure if they are actually blocking the callback or making the recaptcha not work:
Indicate whether to send a cookie in a cross-site request by specifying its SameSite attribute
SharedArrayBuffer usage is restricted to cross-origin isolated sites
I do not even know how to resolve them. As per some articles, they seem to be issues that can only be resolved by Google itself.
Does anyone know why this is happening?
Thanks.
I solved this issue myself by dropping the callback from within and instead I simply called recaptchaVerifier from another function as needed. For example:
First, initialize the recaptcha and render it:
const recaptchaVerifier = new firebase.auth.RecaptchaVerifier('code-button', {
size: 'invisible'
});
recaptchaVerifier.render()
Then, simply call it where needed:
user.multiFactor.getSession().then((multiFactorSession) => {
// Specify the phone number and pass the MFA session.
const phoneInfoOptions = {
phoneNumber: this.state.number,
session: multiFactorSession
};
const phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
// Send SMS verification code.
return phoneAuthProvider.verifyPhoneNumber(
phoneInfoOptions, recaptchaVerifier);
})

Figma React plugin PostMessage not working as expected

I'm trying to create a plugin for Figma, which has been going fine until now. It's based on the react example they provide on their github page: https://github.com/figma/plugin-samples/tree/master/react
In this example I've created a button, that on click will call this function:
(file: ui.tsx)
onClick = () => {
parent.postMessage({pluginMessage: {type: 'GetData'}}, '*');
};
This is parent.postMessage is a function figma provides to communicate with another file in the project, code.ts. This file will receive the postMessage with the pluginMessage as parameter, which works as expected. The code.ts that receives this looks like this:
(file: code.ts)
figma.ui.onmessage = msg => {
if (msg.type === 'GetData') {
figma.ui.postMessage({"title": figma.currentPage.selection[0].name});
}
};
This file receives the message, and it gets in the if statement since GetData has been set. Up until here, everything is good and well. The issue I'm walking into is the figma.ui.postMessage({}), which should do a callback to the onmessage function in ui.tsx:
(file: ui.tsx)
onmessage = (selection) => {
console.log(selection);
};
This onmessage function should, according to Figma's documentation, receive the object from the postMessage in code.ts. This does however never happen; it will never be called at all. I can't access the current selection in ui.tsx, so I need data from code.ts. Is there any way to pass this data to ui.tsx, or does anyone know why this doesn't work?
I encountered the same issue. Within your ui.tsx file, try adding the following:
window.onmessage = selection => {
let message = selection.data.pluginMessage;
console.log(message);
}
or try this ->
window.addEventListener("message", (selection) => {
console.log(selection);
});
this will add another message event handler to the window. if you use onmessage it might overwrite the previous handler!
put first of script
onmessage = event => {
console.log("got this from the plugin code", event, event.data.pluginMessage)
}

Event listener for window.stripe

I have a Stripe integration in a React web front-end. My payment component attempts to run…
componentDidLoad() {
if ( window.hasOwnProperty('Stripe') ) {
this.setState({stripe: window.stripe(config.stripeKey)})
}
}
This sporadically fails as sometimes the React app will boot and get the component loaded before window.stripe exists. I’m currently resolving this with…
componentDidLoad() {
this.watchStripe = setInterval( () => {
if (!props.stripe && isBrowser && window.Stripe) {
this.setState({stripe: window.stripe(config.stripeKey)})
clearInterval(this.watchStripe)
}
}, 100)
}
Is there a more elegant solution to this, something that doesn't require an interval timer?
If you read the Advanced integrations section they suggest doing
componentDidMount() {
if (window.Stripe) {
this.setState({stripe: window.Stripe('pk_test_12345')});
} else {
document.querySelector('#stripe-js').addEventListener('load', () => {
// Create Stripe instance once Stripe.js loads
this.setState({stripe: window.Stripe('pk_test_12345')});
});
}
}
This adds an event listener for the load event on the script element that loads Stripe and sets the state when it is available (so no continuous polling with setInterval,setTimeout is needed)

signalR connection.hub function not called in react component

I'm creating a chatboard and I'm using signalR to let users know when new comment is added on some status/post.
I'm using React and I've tried to add event listeners for the hub function in different components, in some components it works, not others.
This is the hub:
public class CommentHub : Hub
{
public void UpdateComments(int postId)
{
try
{
var context = GlobalHost.ConnectionManager.GetHubContext<CommentHub>();
context.Clients.All.updateNewComments(postId);
}
catch (Exception ex)
{
Log.Error(ex.Message);
}
}
}
I call the event listener in the componentDidMound function:
componentDidMount: function() {
this.commentUpdateListener();
},
And this is the event listener:
commentUpdateListener: function () {
console.log("in the comment update listener!");
var commentHub = $.connection.commentHub;
commentHub.client.updateNewComments = function (postId) {
console.log("updateNewComments called!");
};
$.connection.hub.start();
},
I have a react component for a post/status, a component for the "wall/newsfeed" and then I have a component for the "comment box" for each status on the wall, where the comments are rendered.
When I place the event listener in the wall component or the post component it works, and the 'updateNewComponent' function gets called, but not when I place it in the "comment box" component.
Still "in the comment update listener!" gets logged no matter where I place the event listener, but the hub function is not always called, and it seems to matter in what react component the event listener is placed.
Is the $.connection.commentHub not staying alive? Is it closing?
Is there some reason the function is not always being called?
You can enable logging before starting the hub connection like this :
$.connection.hub.logging = true;
$.connection.hub.start();
If you see some disconnections you can try to restart the connection when it closes :
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
Further reading : Understanding and Handling Connection Lifetime Events in SignalR

Resources