0
votes

I'm trying to request Notification from the frontend but I've being getting this error.

Property or method "requestPermission" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

Within the code, the method requestPermission is correctly spelt. But I'm still facing the same issue.

The Vue Template

<template>
    <div>
        <div class="sticky-top alert alert-primary" v-if="requestPermission"
             v-on:click="enableNotifications">
            Want to know when we publish a new recipe?
            <button class="btn btn-sm btn-dark">Enable Notifications</button>
        </div>
        <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
            <div class="container">
                <router-link :to="{name: 'home'}" class="navbar-brand">Notification PWA</router-link>
                <button
                    class="navbar-toggler"
                    type="button"
                    data-toggle="collapse"
                    data-target="#navbarSupportedContent"
                    aria-controls="navbarSupportedContent"
                    aria-expanded="false"
                >
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav ml-auto">
                        <li>
                            <router-link :to="{name: 'home'}" class="nav-link">Recipes</router-link>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>

    <div class="py-4">
            <router-view></router-view>
        </div>
    </div>
</template>

The Script in Vue.js

<script>
    import firebase from "firebase/app";
    import axios from "axios";
    import "firebase/messaging";

    export default {
        data() {
            return {
                // use a getter and setter to watch the user's notification preference in local storage
                get requestPermission() {
                    return (localStorage.getItem("notificationPref") === null)
                },
                set requestPermission(value) {
                    console.log(value)
                    localStorage.setItem("notificationPref", value)
                }
            }
        }
        ,
        methods: {
            registerToken(token) {
                axios.post(
                    "/api/register-token",
                    {
                        token: token
                    },
                    {
                        headers: {
                            "Content-type": "application/json",
                            Accept: "application/json"
                        }
                    }
                ).then(response => {
                    console.log(response)
                });
            },

            enableNotifications() {
                if (!("Notification" in window)) {
                    alert("Notifications are not supported");
                } else if (Notification.permission === "granted") {
                    this.initializeFirebase();
                } else if (Notification.permission !== "denied") {
                    Notification.requestPermission().then((permission) => {
                        if (permission === "granted") {
                            this.initializeFirebase();
                        }
                    })
                } else {
                    alert("No permission to send notification")
                }
                this.requestPermission = Notification.permission;
            },

            initializeFirebase() {
                if (firebase.messaging.isSupported()) {
                    let config = {
                        apiKey: "xxxxxxxxxxxxxxxxxxx",
                        authDomain: "xxxxxxxxxxxxxx",
                        projectId: "xxxxxxxxxx",
                        messagingSenderId: "xxxxxxxxxxxxx",
                        appId: "xxxxxxxxxxxxxxxxxxxxxxxxxx",
                    };
                    firebase.initializeApp(config);
                    const messaging = firebase.messaging();

                    messaging.getToken()
                        .then((token) => {
                            console.log(token);
                            this.registerToken(token)
                        })
                        .catch((err) => {
                            console.log('An error occurred while retrieving token. ', err);
                        });

                    messaging.onMessage(function (payload) {
                        console.log("Message received", payload);
                        let n = new Notification("New Recipe alert!")
                    });
                }
            }
        }
    };
    

Is there any way I can resolve this issue?

1
your get & set requestPermission methods should be inside a computed propChristian Carrillo

1 Answers

0
votes

I think that you should use a computed property for that:

export default {
  data () {
    return {
      requestPermissionValue: null
    }
  },
  computed: {
    requestPermission: {
      get () {
        return this.requestPermissionValue
      },
      set (value) {
        this.requestPermissionValue = value
        localStorage.setItem("notificationPref", value)
      }
    }
  },
  created () {
    this.requestPermissionValue = localStorage.getItem("notificationPref") === null
  }
}

As long as you don't change the notificationPref localStorage item in another component, it should work fine for you.

The created hook makes an initial copy of the localStorage based value. localStorage is not reactive, this is why you need a property in data.