Skip to content

FirebaseError: Firebase: Need to provide options, when not being deployed to hosting via source. (app/no-options) #7262

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
hsubox76 opened this issue Apr 25, 2023 · 7 comments

Comments

@hsubox76
Copy link
Contributor

hsubox76 commented Apr 25, 2023

"app/no-options" error seen in service worker script as described in discussion here: #7180 (reply in thread)

For anyone else reporting this error, can you describe

  • where and how are you calling initializeApp (in a service worker or somewhere else?)
  • what version you're seeing it in
  • what's the last version you're not seeing it in

Original discussion post copied below:

I am getting this error on my firebase app, here is my service worker file firebase-messaging-sw.js:

import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { getAuth } from 'firebase/auth';

export const app = initializeApp({
  apiKey: "XXXXXXXXXXXXXXXXXXXXXXX-XXXXXX",
  authDomain: "XXXXXXXXXXXXXXXXXXXXXXXXX",
  projectId: "XXXXXXXXXX-XXXXX",
  storageBucket: "XXXXXXXXXXX-XXXXXXXXXXXXX",
  messagingSenderId: "XXXXXXXXXX--XXXXX",
  appId: "XXXXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXX-X",
  measurementId: "XXXXXXX---XXXXXXXXXX"
});

export const db = getFirestore(app);
export const auth = getAuth(app);
import { Injectable } from '@angular/core';
import {BehaviorSubject} from "rxjs";
import {AngularFireMessaging} from "@angular/fire/compat/messaging";
import { getMessaging, getToken } from "firebase/messaging";



@Injectable({
  providedIn: 'root'
})

export class MessagingService {

  currentMessage = new BehaviorSubject(null);

  constructor(private angularFireMessaging: AngularFireMessaging) {
  }

  requestPermission() {
    console.log('Requesting permission...');
    Notification.requestPermission().then((permission) => {
      if (permission === 'granted') {
        console.log('Notification permission granted.');
      }
    })
  }

    requestForToken = () => {
      if ("serviceWorker" in navigator) {
        navigator.serviceWorker.register("./firebase-messaging-sw.js").then(function(registration) {
          console.log("Registration successful, scope is:", registration.scope);
        })
      }
    return getToken(getMessaging(), { vapidKey: '' }) //ERROR OCCURS HERE
      .then((currentToken) => {
        if (currentToken) {
          console.log('current token for client: ', currentToken);
          // Perform any other neccessary action with the token
        } else {
          // Show permission request UI
          console.log('No registration token available. Request permission to generate one.');
        }
      })
      .catch((err) => {
        console.log('An error occurred while retrieving token. ', err);
      });
  };

}

Here is my app component file:

import { Component, OnInit } from '@angular/core';
import {Message} from "./models/message";
import {AngularFireMessaging} from "@angular/fire/compat/messaging";
import {HttpClient} from "@angular/common/http";
import {MessagingService} from "./messaging.service";


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'untitled3';

  messages: Array<Message> = [];

  constructor(private msg: AngularFireMessaging, private http: HttpClient, private service: MessagingService) { }

  ngOnInit() {
    this.service.requestPermission();
    let x = this.service.requestForToken();
    console.log(x);

  }
}

Please see the stacktrace below for the detailed error:

ERROR FirebaseError: Firebase: Need to provide options, when not being deployed to hosting via source. (app/no-options).
at initializeApp (index.esm2017.js:423:29)
at getApp (index.esm2017.js:476:16)
at getMessagingInWindow (index.esm2017.js:1159:43)
at MessagingService.requestForToken (messaging.service.ts:47:33)
at AppComponent.ngOnInit (app.component.ts:23:26)
at callHook (core.mjs:2450:22)
at callHooks (core.mjs:2419:17)
at executeInitAndCheckHooks (core.mjs:2370:9)
at refreshView (core.mjs:10357:21)
at detectChangesInternal (core.mjs:11545:9)
I am using Angular Please assist. I have tried the following approaches

I tried adding the auth information

I Tried registering the service worker on both the index and the messaging service class

I tried calling the service worker module on the app module and calling the register there

Still no luck

@hsubox76
Copy link
Contributor Author

Looking through the code, in general this error seems to happen when getApp() is called before initializeApp(). In this specific case, getApp() is called by getMessaging(), which is called by the user on the line labeled ERROR OCCURS HERE.

Either getMessaging() is being executed before initializeApp(), or maybe initializeApp() isn't being executed at all in that second file. Is it a separate file from the first one?

The situation may be different for other users reporting errors, but I think the error reflects initializeApp() either not being called, or somehow being executed after calling getMessaging() or get/initialize functions for any other product instance.

If this doesn't seem to be the case for you, let me know. I will also work on getting a more helpful error message in this case.

@VictorKabine2
Copy link

Hi @hsubox76 the initializeApp() is initialized in the service worker. How do I ensure that the initialize app is called first

@hsubox76
Copy link
Contributor Author

The service worker is a different context and I don't think your main app (? is that what the second code block is?) can access variables in it. You should be calling initializeApp() in your main app code somewhere, or if AngularFire has a different way to do it, using that. I'm not really familiar with AngularFire but are you supposed to be mixing AngularFire imports and imports directly from the Firebase SDK like that? I thought if you were using AngularFire you're supposed to be getting all your Firebase imports through the Angularfire library: https://github.com/angular/angularfire

Also it's best practice to pass the app object into get[Product] calls and not rely on the implicit default app.

const app = initializeApp({ /* config */ });
const messaging = getMessaging(app);

It's not necessary, but explicit passing makes your code clearer and it helps you avoid mistakes, like in this case, in the second file (? I assume the second code block is a second file) you never created an app and you'd realize that when you tried to pass it into getMessaging(). If you leave it implicit it's easy to miss it was never created.

@VictorKabine2
Copy link

VictorKabine2 commented Apr 30, 2023

Hi @hsubox76 I have updated the code with the angular fire imports and added get messaging however I still get the error:

here is my service worker file firebase-messaging-sw.js:

import { initializeApp } from 'firebase/app';
import { getFirestore } from '@angular/fire/firestore';
import { getAuth } from '@angular/fire/auth';
import {getMessaging} from '@angular/fire/messaging';

export const app = initializeApp({
  apiKey: "AIzaSyCWaH06ES-O1HX4L1EExrjnRtr0Maf1wX8",
  authDomain: "my-project2-379e3.firebaseapp.com",
  projectId: "my-project2-379e3",
  storageBucket: "my-project2-379e3.appspot.com",
  messagingSenderId: "496119910171",
  appId: "1:496119910171:web:8fb2b509d28c8a0d928dbe",
  measurementId: "G-BMEJJGZ2DG"
});

export const db = getFirestore(app);
export const auth = getAuth(app);

export const messaging = getMessaging(app);

Here's the service file:

import { Injectable } from '@angular/core';
import {BehaviorSubject} from "rxjs";
import {AngularFireMessaging} from "@angular/fire/compat/messaging";
import { getMessaging, getToken } from "@angular/fire/messaging";

@Injectable({
  providedIn: 'root'
})

export class MessagingService {

  currentMessage = new BehaviorSubject(null);

  constructor(private angularFireMessaging: AngularFireMessaging) {
  }

  requestPermission() {
    console.log('Requesting permission...');
    Notification.requestPermission().then((permission) => {
      if (permission === 'granted') {
        console.log('Notification permission granted.');
      }
    })
  }
  requestToken() {
    console.log("Inside the request token method...")
    this.angularFireMessaging.getToken.subscribe(
      (token) => {
        // alert(1234567890)
        console.log(token)
        // console.log('permission granted', token)
      },
      (err) => {
        alert(err)
        console.error('Unable to get permission to notify.', err);
      }
    );
  }

    requestForToken = async () => {
      const messaging = getMessaging();
      if('serviceWorker' in navigator) {
        navigator.serviceWorker.register('firebase-messaging-sw.js')
          .then(function(registration) {
            console.log("Service Worker Registered");
          });
      }
      return getToken(messaging, {vapidKey: 'AIzaSyCWaH06ES-O1HX4L1EExrjnRtr0Maf1wX8'}) 
        .then((currentToken) => {
          if (currentToken) {
            console.log('current token for client: ', currentToken);
            // Perform any other neccessary action with the token
          } else {
            // Show permission request UI
            console.log('No registration token available. Request permission to generate one.');
          }
        })
        .catch((err) => {
          console.log('An error occurred while retrieving token. ', err);
        });
    };

}

Here is my app component file:

import { Component, OnInit } from '@angular/core';
import {Message} from "./models/message";

import {HttpClient} from "@angular/common/http";
import {MessagingService} from "./messaging.service";
import {AngularFireMessaging} from "@angular/fire/compat/messaging";


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'untitled3';

  messages: Array<Message> = [];

  constructor(private msg: AngularFireMessaging, private http: HttpClient, private service: MessagingService) { }

  ngOnInit() {
    this.service.requestPermission();
    let x = this.service.requestForToken();
    console.log(x);

//    this.service.requestToken();

  }
}

Please see the stacktrace below for the detailed error:

ERROR Error: Uncaught (in promise): FirebaseError: Firebase: Need to provide options, when not being deployed to hosting via source. (app/no-options).
FirebaseError: Firebase: Need to provide options, when not being deployed to hosting via source. (app/no-options).
    at initializeApp (index.esm2017.js:423:29)
    at getApp (index.esm2017.js:476:16)
    at getMessagingInWindow (index.esm2017.js:1159:43)
    at angular-fire.js:227:48
    at angular-fire.js:160:59
    at _ZoneDelegate.invoke (zone.js:375:26)
    at Zone.run (zone.js:134:43)
    at NgZone.runOutsideAngular (core.mjs:24101:28)
    at runOutsideAngular (angular-fire.js:160:35)
    at angular-fire.js:227:21
    at resolvePromise (zone.js:1214:31)
    at zone.js:1121:17
    at zone.js:1137:33
    at asyncGeneratorStep (asyncToGenerator.js:6:1)
    at _next (asyncToGenerator.js:22:1)
    at asyncToGenerator.js:27:1
    at new ZoneAwarePromise (zone.js:1432:21)
    at MessagingService.requestForToken (asyncToGenerator.js:19:1)
    at AppComponent.ngOnInit (app.component.ts:23:26)
    at callHook (core.mjs:2450:22)

@VictorKabine2
Copy link

@hsubox76 The error doesn't point to the message service file anymore

@hsubox76
Copy link
Contributor Author

hsubox76 commented May 1, 2023

I don't know what the "service file" is or what role it plays in your app architecture, but I still don't see you calling initializeApp() in it. The angularfire stuff I mentioned isn't related to your issue, or I don't think it is, I just thought it looked odd, and it still does, you have both compat and modular messaging which doesn't seem right - but that's a different topic. The important thing is to call initializeApp() before getMessaging(). It doesn't look like that's happening.

I think as far as the SDK is concerned, I don't see a bug, as it definitely looks like you're not calling initializeApp() before getMessaging(). If you're able to guarantee those are being called in the same file or context in that order, and still see this problem (or if any other users do the same), let me know and I'll reopen the issue.

@hsubox76 hsubox76 closed this as completed May 1, 2023
@VictorKabine2
Copy link

This is very worrying, I am following all these tutorials on how to set up Angular with FCM:

https://benjaminbekes.medium.com/angular-12-and-firebase-cloud-messaging-fcm-v9-abbeb9dc3e1e

https://medium.com/mighty-ghost-hack/angular-8-firebase-cloud-messaging-push-notifications-cc80d9b36f82

https://medium.com/@jishnusaha89/firebase-cloud-messaging-push-notifications-with-angular-1fb7f173bfba

https://stackoverflow.com/questions/62585033/angular-push-notification-with-fcm

https://medium.com/@a.adendrata/push-notifications-with-angular-6-firebase-cloud-massaging-dbfb5fbc0eeb

https://www.devstringx.com/firebase-cloud-messaging-push-notifications

https://www.section.io/engineering-education/fcm-with-spring-and-angular/#setting-up-firebase-on-our-front-end

The fact that none of them, none of them are set up correctly means that there isn't a single working example of an Angular FCM project

@firebase firebase locked and limited conversation to collaborators Jun 1, 2023
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

2 participants