6

I make an C# API to push notification to Flutter app.

My API basically like code below :

public async Task < IActionResult > pushNotification () {
  FirebaseApp.Create(new AppOptions() {
    Credential = GoogleCredential.FromFile("file.json")
  });
  .....
} 

I past url "domain.com/api/controller/pushNotification" on my browser, the first time it's work. My flutter receive notification perfectly. But the second time I got :

System.ArgumentException: The default FirebaseApp already exists.
   at FirebaseAdmin.FirebaseApp.Create(AppOptions options, String name)
   at FirebaseAdmin.FirebaseApp.Create(AppOptions options)

Why ? And how can I fix that ?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Alex
  • 727
  • 1
  • 13
  • 32

5 Answers5

15

You can simply check whether there is or isn't a FirebaseApp Instance by

if (FirebaseApp.DefaultInstance == null)
    {
        App = FirebaseApp.Create(new AppOptions()
        {
            Credential = GoogleCredential.FromFile("file.json")
        });
    }
Carset
  • 153
  • 4
2

Carset answer took me really close to what I needed.

I just changed my constructor to look this way and worked perfect

public MobileMessagingClient()
    {
        var app = FirebaseApp.DefaultInstance;
        if (FirebaseApp.DefaultInstance == null)
        {
            app = FirebaseApp.Create(new AppOptions()
            {
                Credential = GoogleCredential.FromFile(HttpContext.Current.Server.MapPath("~/file.json"))
            .CreateScoped("https://www.googleapis.com/auth/firebase.messaging")
            });
        }            
        messaging = FirebaseMessaging.GetMessaging(app);
    }
  • Please don't add "thank you" as an answer. Instead, vote up the answers that you find helpful. - [From Review](/review/late-answers/32447301) – Matthias Auswöger Aug 16 '22 at 15:50
1

Firebase manages its own client internally, you can reference it by calling methods for Firebase which make a request to the defined or default "App" since you can technically have multiple Apps.

You most likely only want to initiate the Firebase App only if one does not already exist. I believe you can do this by checking the FirebaseApp.apps length - you should

DIGI Byte
  • 4,225
  • 1
  • 12
  • 20
1

the first time it's work. My flutter receive notification perfectly. But the second time I got

Your error message is saying that you're trying to initialize an app that already exists.

To fix this, you need to first check if the app has been initialized. Before running your piece of code that initializes the Firebase app, add a simple check, for example:

public async Task < IActionResult > pushNotification () {
if(appDoesNotExistYet) {
  FirebaseApp.Create(new AppOptions() {
    Credential = GoogleCredential.FromFile("file.json")
  });
}

  .....
} 
Hydra
  • 950
  • 4
  • 7
0

If you use the default constructor without name it creates the default instance.

    /// <summary>Creates an app with the specified name and options.</summary>
    /// <returns>The newly created <see cref="T:FirebaseAdmin.FirebaseApp" /> instance.</returns>
    /// <exception cref="T:System.ArgumentException">If the default app instance already
    /// exists.</exception>
    /// <param name="options">Options to create the app with. Must at least contain the
    /// <c>Credential</c>.</param>
    /// <param name="name">Name of the app.</param>
    public static FirebaseApp Create(AppOptions options, string name)
    {
      if (string.IsNullOrEmpty(name))
        throw new ArgumentException("App name must not be null or empty");
      options = options ?? FirebaseApp.GetOptionsFromEnvironment();
      lock (FirebaseApp.Apps)
      {
        if (FirebaseApp.Apps.ContainsKey(name))
        {
          if (name == "[DEFAULT]")
            throw new ArgumentException("The default FirebaseApp already exists.");
          throw new ArgumentException("FirebaseApp named " + name + " already exists.");
        }
        FirebaseApp firebaseApp = new FirebaseApp(options, name);
        FirebaseApp.Apps.Add(name, firebaseApp);
        return firebaseApp;
      }
    }

Hence if you have multiple apps (Projects) that you want to use, then you need to use the overload with name. You can use name as ProjectId or any other Identifier.

var instance = FirebaseApp.GetInstance(appOptions.ProjectId) ?? FirebaseApp.Create(appOptions, appOptions.ProjectId);
Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112