Is it possible to configure multiple Firebase projects for my Unity application without diving into the Android or iOS code? I tried simply switching out the google-services.json file, but this failed to point my Unity app to the correct Firebase app. Ideally I'd like to be able to do something like this:
void Awake()
{
if (environment == Environment.Development)
{
SetDevelopmentEnvironment();
}
FirebaseApp.CheckDependencies();
FirebaseApp.FixDependenciesAsync();
auth = FirebaseAuth.DefaultInstance;
}
public void SetDevelopmentEnvironment()
{
AppOptions firebaseDevelopmentAppOptions = new AppOptions();
firebaseDevelopmentAppOptions.ProjectId = "test";
firebaseDevelopmentAppOptions.StorageBucket = "test.appspot.com";
firebaseDevelopmentAppOptions.AppId = "1:12345:android: xyz";
firebaseDevelopmentAppOptions.ApiKey = "123Key";
firebaseDevelopmentAppOptions.MessageSenderId = "123SenderID";
System.Uri dbURL = new System.Uri("https://test.firebaseio.com");
firebaseDevelopmentAppOptions.DatabaseUrl = dbURL;
FirebaseApp.Create(firebaseDevelopmentAppOptions);
}
Or better yet, simply pass the appropriate google-services.json from the Resources folder.
To add more information on Unity specifically:
The shortest answer is that right now, multiple configurations are not officially supported by the Unity plugin. There are a number of custom processes put into place for backwards compatibility
The way this works on Android is that the script generate_xml_from_google_services_json.py
converts your google-services.json
file into google-services.xml
and places it in a place that gets copied over to the Android build (note that on Windows, this is compiled into generate_xml_from_google_services_json.exe
so developers don't have to install python). Ths means that when you swap out this file, you need to make sure the xml gets regenerated (and if you export an Android project before changing your google-services
file, then you need to replace the xml rather than the json). This basically duplicates the process of the google services plugin whilst also maintaining backwards compatibility with versions of Unity that predate gradle support. Since it does use the Android resources system, this would be hard to swap out after building a game.
On iOS, GoogleServices-Info.plist
is copied over to the final XCode project. It would be rather simple to replace this at any point in your build process, although it wouldn't be easy to swap out after making a build.
Now to do what you first ask in your question, if you can do it at run time in some way. You have to be really careful, Firebase in Unity is a lazily initialized singleton. That is, accessing the property FirebaseApp.DefaultInstance
or invoking any function that depends on it will cause a Firebase singleton to be created. You can try manually create a Firebase instance with FirebaseApp.Create(AppInfo)
, but you'll have to be very structured in your game design to ensure that it gets called before FirebaseApp
is implicitly constructed (Create should setup the global default instance, but CheckAndFixDependenciesAsync
is an async call that may take more than one frame to complete. This could present a tricky bug surface). You can pass in AppOptions generated from a json file as @Twinsens points out, but having multiple files named google-services.json
in your Assets/
directory is not a well defined scenario. You will want to rename your non-default configurations (likely changing the extension to .txt
as well so you can retrieve them as a TextAsset
).
Something like this:
async void Awake()
{
var dependencyStatus = await FirebaseApp.CheckAndFixDependenciesAsync();
if (dependencyStatus != DependencyStatus.Available) {
// error handling here
return;
}
FirebaseApp app;
if (environment == Environment.Development)
{
// I'm being extra cautious. `DefaultInstance` should have the one you create.
app = SetDevelopmentEnvironment();
}
else {
app = FirebaseApp.DefaultInstance;
}
// I'm being extra explicit just in case
// for large projects, I'd prefer some sort of DI over the singletons anyway
auth = FirebaseAuth.GetAuth(app);
}
public FirebaseApp SetDevelopmentEnvironment()
{
AppOptions firebaseDevelopmentAppOptions = new AppOptions();
firebaseDevelopmentAppOptions.ProjectId = "test";
firebaseDevelopmentAppOptions.StorageBucket = "test.appspot.com";
firebaseDevelopmentAppOptions.AppId = "1:12345:android: xyz";
firebaseDevelopmentAppOptions.ApiKey = "123Key";
firebaseDevelopmentAppOptions.MessageSenderId = "123SenderID";
System.Uri dbURL = new System.Uri("https://test.firebaseio.com");
firebaseDevelopmentAppOptions.DatabaseUrl = dbURL;
return FirebaseApp.Create(firebaseDevelopmentAppOptions);
}
You can try this;
AppOptions.LoadFromJsonConfig(string json);
for more information please visit,
https://firebase.google.com/docs/reference/unity/class/firebase/app-options#loadfromjsonconfig
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With