Skip to content

FCM Notification showing ["This site has been updated in the background"] #3868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
salek-zylk opened this issue Sep 30, 2020 · 2 comments
Closed

Comments

@salek-zylk
Copy link

[REQUIRED] Describe your environment

  • Operating System version: Ubuntu 20.04
  • Browser version: Versión 85.0.4183.102 (Build oficial) (64 bits)
  • Firebase SDK version: 7.19.1
  • Firebase Product: messaging

[REQUIRED] Describe the problem

I have implemented push notifications (foreground and background) in web app (REACT) throught firebase system. In mobile, i have received twice notifications push in background: the notification sent (correct) and one more with a generic message This site has been update in the background" (incorrect). In desktop with chrome, only recived the generic notification (incorrect).

Relevant Code:

https://stackblitz.com/fork/firebase-issue-sandbox
firebase-messaging-sw.js

/* eslint-disable no-undef */
// Import and configure the Firebase SDK
// These scripts are made available when the app is served or deployed on Firebase Hosting
// If you do not serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup
importScripts('https://www.gstatic.com/firebasejs/7.19.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.19.1/firebase-messaging.js');
importScripts('js/javascript-helper.js');

// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();

// eslint-disable-next-line no-restricted-globals
self.addEventListener('notificationclick', function(event) {

  event.notification.close();
  event.waitUntil(
    Promise.all([
      clients.openWindow(event.notification.data.url),
      sendAnalyticsEvent(trackingId, event.notification.data.pushId, 'Notificación Abierta')
    ])
  );

  
}
, false);


// background (Web app is closed or not in browser focus) then you should
// implement this optional method.
// [START background_handler]
messaging.setBackgroundMessageHandler(function(payload) {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notification = payload.notification ? payload.notification : payload.data.message ? JSON.parse(payload.data.message).notification : payload.data.payload ? JSON.parse(payload.data.payload).notification : JSON.parse(payload);
  const notificationTitle = notification.title || 'Background Message Title';
  const notificationOptions = {
    body: notification.body || 'Background Message body.',
    tag: notification.tag || 'Push Notification',
    icon: '/new-logo192.png',
    data: { 
    	url: notification.url, pushId: notification.pushId
	}
  };
  
  sendAnalyticsEvent(trackingId, notification.pushId, 'Notificación Recibida');
  console.log("tag: " + notification.tag);
  // eslint-disable-next-line no-restricted-globals
  return self.registration.showNotification(notificationTitle,
      notificationOptions);
});
// [END background_handler]

Component TSX in REACT (for notification in foreground)

interface NotificationPushProps extends RouteComponentProps {
    user: model.User
    token: string
}

interface NotificationPushState {
    fcmToken: string,
    showPerm: boolean;
    title: string,
	url: string,
    body: string,
	pushId: string,
    showMessage: boolean;
}

class NotificationPush extends React.Component<NotificationPushProps, NotificationPushState> {
    constructor(props: NotificationPushProps, state: NotificationPushState) {
        super(props, state);
        this.state = {
            fcmToken: '',
            showPerm: false,
            title: '',
			url: '',
            body: '',
			pushId: '',
            showMessage: false
        }
    }

    componentDidMount() {
        // [START refresh_token]
        // Callback fired if Instance ID token is updated.

        if (isChrome && !isIOS) {
            firebase.messaging().onTokenRefresh(() => {
                firebase.messaging().getToken()
                    .then((refreshedToken: string) => {
                        console.log('Token refreshed.');
                        // Indicate that the new Instance ID token has not yet been sent to the
                        // app server.
                        this.setTokenSentToServer(false);
                        // Send Instance ID token to app server.
                        this.sendTokenToServer(refreshedToken);
                        // [START_EXCLUDE]
                        // Display new Instance ID token and clear UI of all previous messages.
						this.requestPermission();
                        this.resetUI();
                        // [END_EXCLUDE]
                    })
                    .catch((err) => {
                        console.log('Unable to retrieve refreshed token ', err);
                    });
            });
        }
        // [END refresh_token]

        // [START receive_message]
        // Handle incoming messages. Called when:
        // - a message is received while the app has focus
        // - the user clicks on an app notification created by a sevice worker
        //   `messaging.setBackgroundMessageHandler` handler.
        if (isChrome && !isIOS) {

            firebase.messaging().onMessage((payload) => {
                // [START_EXCLUDE]
                // Update the UI to include the received message.
                //appendMessage(payload);
		        const notification = payload.notification ? payload.notification : payload.data.message ? JSON.parse(payload.data.message).notification : payload.data.payload ? JSON.parse(payload.data.payload).notification : JSON.parse(payload);
		        const notificationId = notification.pushId;
				console.log("notificacion recibida: " + notificationId);
				api.gaEvent('Notificación Recibida', notificationId);
                this.showMessage(payload);
                // [END_EXCLUDE]
            });

            this.resetUI();
        }
    }

    resetUI = () => {

        if (isChrome && !isIOS) {
            // [START get_token]
            // Get Instance ID token. Initially this makes a network call, once retrieved
            // subsequent calls to getToken will return from cache.
            firebase.messaging().getToken()
                .then((currentToken: string) => {
					console.log("1111: " + currentToken);
                    if (currentToken) {
                        this.sendTokenToServer(currentToken);

                    } else {
						console.log("3333: " + currentToken);
                        // Show permission request.
                        console.log('No Instance ID token available. Request permission to generate one.');
                        // Show permission UI.
                        this.updateUIForPushPermissionRequired();
                        this.setTokenSentToServer(false);
                    }
                })
                .catch((err) => {
                    console.log('An error occurred while retrieving token. ', err);
					if(err == "FirebaseError: Messaging: The notification permission was not granted and blocked instead. (messaging/permission-blocked)."){
						console.log('antes de lanzar la petición');
						api.cleanUserFcmtokens(this.props.user, this.props.token)
						console.log('después de lanzar la petición');
					}else{
						console.log("err:" + err);
					}
                    this.setTokenSentToServer(false);
                });
        }
    }

    // Send the Instance ID token your application server, so that it can:
    // - send messages back to this app
    // - subscribe/unsubscribe the token from topics

    sendTokenToServer = (currentToken: string) => {
        if (isChrome && !isIOS) {
            if (!this.isTokenSentToServer()) {
                api.updateUserFcmtokens(this.props.user, currentToken, this.props.token)
                    .then(() => {
                        console.log("zk: OK");
                    })
                    .catch(error => {
                        console.log("zk: KO");
                    });

                // TODO(developer): Send the current token to your server.
                this.setTokenSentToServer(true);
            } else {
                console.log('Token already sent to server so won\'t send it again unless it changes');
            }
        }
    }

    isTokenSentToServer = () => {
        return window.localStorage.getItem('sentToServer') === "1";
    }

    setTokenSentToServer = (sent: boolean) => {
        window.localStorage.setItem('sentToServer', sent ? "1" : "0");
    }

    requestPermission = () => {
        console.log('Requesting permission...');
        // [START request_permission]
        firebase.messaging().requestPermission()
            .then(() => {
                // TODO(developer): Retrieve an Instance ID token for use with FCM.
                // [START_EXCLUDE]
                // In many cases once an app has been granted notification permission, it
                // should update its UI reflecting this.
                this.resetUI();
                // [END_EXCLUDE]
            })
            .catch(function (err) {
                console.log('Unable to get permission to notify.', err);
            });
        // [END request_permission]
    }

    showMessage = (payload: any) => {
        const notification = payload.notification ? payload.notification : payload.data.message ? JSON.parse(payload.data.message).notification : payload.data.payload ? JSON.parse(payload.data.payload).notification : JSON.parse(payload);
        const notificationTitle = notification.title || 'Foreground Message Title';
        const notificationBody = notification.body || 'Foreground Message body.';
        const notificationId = notification.pushId;
        const notificationUrl = notification.url;
		console.log("notificacion recibida2: " + notificationId);
        this.setState({
            title: notificationTitle,
			url: notificationUrl,
            body: notificationBody,
			pushId: notificationId,
            showMessage: true
        });

		const MyMsg = () => (
		  <div className="notification-block row">
            <div className="notification-info col-10">
                <div className="notification-title">
                    <FiBell size="1em"/>{notificationTitle}
                    </div>
                <div className="notification-description">{notificationBody}</div>
            </div>
            <img className="notification-image col-2" alt="" src={logo}/>
		  </div>
		)
		
	    toast(MyMsg);
		
    }


    updateUIForPushPermissionRequired = () => {
        this.setState({ showPerm: true });
    }

    hideMessage = () => {
        this.setState({
            showMessage : false,
            title: '',
            body: ''
        });
    }
   
    onOpenUrl = () => {
		console.log("notificacion abierta");
		api.gaEvent('Notificación Abierta', this.state.pushId);		
    }
	
    render() {
        return (
            <div>
		      <a target="_blank" onClick={this.onOpenUrl} href={this.state.url} >
  				<ToastContainer
					position="bottom-right"
					hideProgressBar={true}
					newestOnTop={false}
					closeOnClick
					rtl={false}
					pauseOnFocusLoss
					draggable
					pauseOnHover
					closeButton={false}
					autoClose={false}
				>
				</ToastContainer>
			</a>
			</div>
        );
    }

}

export default withRouter(NotificationPush);
@Feiyang1
Copy link
Member

Duplicate of #3725. Closing.

We already have a PR open to address this issue.
I'm not sure why desktop chrome only shows the generic notification though.

FYI, @zwu52

@zwu52
Copy link
Member

zwu52 commented Sep 30, 2020

@salek-zylk
From your code it looks like you are covering the use case where a display notification fields being both in notification payload and/or data payload. Can you share your send request?

@firebase firebase locked and limited conversation to collaborators Oct 31, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants