Open paularius opened 6 years ago
@paularius could you try adding a string entry to your project (in strings.xml
)
<!-- Use the same value you used for applicationID above -->
<string name="google_app_id">YOUR_APPLICATION_ID</string>
For a more comprehensive guide on not using the json
file, see this blog post:
https://medium.com/@samstern_58566/how-to-use-firebase-on-android-without-the-google-services-plugin-93ecc7dc6c4
@samtstern Thanks for your reply. I have already tried this, and seems to work. The thing is that I would like to initialize the FirebaseApp more dynamically, since I would like to have different projects within the same apk (so using different flavors for the xml, would not be useful). I am trying a part of your approach and try to change the resource dynamically, using reflection, before initializeApp, but that doesn't seem to work either. Moreover, what is the use of the FirebaseOptions, if I have to use a file in my project?
@paularius you're right that you shouldn't need the XML file at all. Where are you calling InitializeApp()
and is it possible you're trying to use FirebaseAnalytics
before that happens?
@samtstern I call it first thing in onCreate, in my application class. Also, before I try to use any firebaseAnalytics call, I check that the FirebaseApp (the "[DEFAULT]" one) exists. But even if I tried to initialize it in some other place (for example when I get a response from my server), even by losing some events, should it be a problem?
I have had the same issue since months now. I have a running thread with the support team, and it doesn't look like this issue is going anywhere. In my scenario, I have the manual Firebase initialization in a library, and I have multiple apps that use that library. So based on the application thats using it, I initialize the Firebase app. Everything initializes well, but Firebase analytics, which complains about "Missing google_app_id".
We're having the same issue, really hope Firebase team moves faster on this as it's impacting many developers and we're considering moving off of Firebase due to it.
Thanks everyone for chiming in! I filed an internal bug (b/117609738) with the analytics team since they're likely not watching this issue as that SDK is still closed source. Hopefully they can help me get to the bottom of this.
If you'll let me take one more blind stab: what happens if you create a bogus google_app_id
string resource just to satisfy the SDK, but then initialize the default FirebaseApp
yourself at runtime. Does Analytics send events to the right place?
@samtstern if I just add a google app id, Firebase initializes the app on its own, but ofc doesn't add the other parameters like database url etc. So the manual initialization also fails, because it sees that the app has already been initialized. I even tried to add all the items as generated by firebase to my resources, as mentioned in this post: https://medium.com/@samstern_58566/how-to-use-firebase-on-android-without-the-google-services-plugin-93ecc7dc6c4. It works, but then like @paularius mentioned, I wouldn't be able to switch the app environments dynamically during run time.
Please, I have same problem with initialization app, is this problem solved yet, or exist any workaround?
There's no PR yet for that? How is going on the work to solve that?
I'm with the same problem, I want to load dynamically apps on runtime.
Is this issue fixed...I mean can we initialize firebase without this json file.. Also what is the purpose of firebaseoptions.builder if we can intialize firebase without the builder by simply copying the json file in project.
Yes, we have similar requirement where we would like to be able to switch on startup which Firebase project along with Analytics and Crashlytics should be used. Any feedback from Analytics teams on this?
Hi, we also have the same issue, it's stopping us from full migration from GA to Firebase because we need to setup Firebase in runtime with use of data received from our backend. Is there any ongoing work on this bug?
Having the same issue. Will be there any fix soon?
@samtstern Any news here?
@samtstern Any update on this issue?
Google Analytics for Firebase (GA4F) doesn't support dynamic initialization. Our engineers are checking the possible solutions to support this. It's just that we still haven't found a definite timeline as to when (or if) this will be available. GA4F will not work without the google-services.json file (or Gradle on your end). Even though you can initialize the FirebaseApp dynamically through code, GA4F will not recognize this and will only result in the error message you are seeing. The scenario you are getting is only specific to Google Analytics for Firebase. However, you can still use other products like Firestore, Realtime Database, Storage even if you are not using Gradle plugin.
Just checking up on this, status of this has not changed, right?
@pepitoria AFAIK the last time we spoke with google - this issue is not going to be resolved.
bug with Firebase using in Chromium
in Chromium problem was due to string resources obfuscation (so google_app_id was obfuscated). adding resource_type/resource_name#no_obfuscate in aapt2.config solved problem
Copied from https://github.com/firebase/firebase-android-sdk/issues/187#issuecomment-635485459
Thanks for the question and for waiting patiently.
Many Firebase SDKs products provide an overload that allows you to pass in a custom FirebaseApp getInstance(FirebaseApp)
.
This API will allow you inject these Firebase instances as dependencies into your application code so they continue remaining agnostic to prod,staging,dev versions of your app.
I suspect your question pertains to eagerly initialized SDKs like Analytics, Crashlytics and Firebase Performance that require no developer interaction and start working automagically once included in the app. Note that these SDKs do not support the desired getInstance(FirebaseApp)
overload.
The challenge with designing an API like getInstance(FirebaseApp)
for these products is that it would have to be wired in super early in the App's lifecycle, to (say) allow Crashlytics to capture crashes that happen early on, or to (say) allow Performance to capture app start metrics early on.
In the absence of this API, you may be able to do this by disabling the default init provider and creating your own equivalent. The key here is to perform the custom initialization super early in your app's lifecycle, like in a Content Provider.
FirebaseOptions.Builder builder = new FirebaseOptions.Builder()
.setApplicationId("1:0123456789012:android:0123456789abcdef")
.setApiKey("your_api_key")
.setDatabaseUrl("https://your-app.firebaseio.com")
.setStorageBucket("your-app.appspot.com");
FirebaseApp.initializeApp(this, builder.build());
I realize is a suboptimal experience. It does get the job done for now. Feel free to propose ideas you may have to help up build an API to accommodate the nuance I described above.
Sadely @ashwinraghav this doesn't seem to solve the issue. We have struggled with this for almost two years. We have a multi-tenant application with dynamic switching of the firebase project and we got that working but analytics has to all be sent to one place by hardcoding "google_app_id" in values/strings.xml - this is the only thing that somewhat works. I just tried a Content Provider and the code runs fine but still see an error "Missing google_app_id." We continue to wait hopefully for one day a getInstance(FirebaseApp) for FirebaseAnalytics. Note this all works for the iOS SDKs.
Sadely @ashwinraghav this doesn't seem to solve the issue. We have struggled with this for almost two years. We have a multi-tenant application with dynamic switching of the firebase project and we got that working but analytics has to all be sent to one place by hardcoding "google_app_id" in values/strings.xml - this is the only thing that somewhat works. I just tried a Content Provider and the code runs fine but still see an error "Missing google_app_id." We continue to wait hopefully for one day a getInstance(FirebaseApp) for FirebaseAnalytics. Note this all works for the iOS SDKs.
Duly noted. This feedback is helpful for us to prioritize.
Is it possible to set up Firebase Cloud messaging from the instance of the second app ?
We are also affected from this issue since we are using a content provider instead of google-services.json
. We are trying to migrate to firebase crashlytics with mappingFileUploadEnabled
set to true. The build fails with the following error:
Crashlytics could not find the resource file generated by Google Services. You may need to execute the :process<Variant>GoogleServices Task. Please check your Firebase project configuration (https://firebase.google.com/docs/android/setup).
The issue is two years old and it is the highest voted firebase sdk github issue, shouldn't it have a top priority?
We are also affected from this issue since we are using a content provider instead of
google-services.json
. We are trying to migrate to firebase crashlytics withmappingFileUploadEnabled
set to true. The build fails with the following error:Crashlytics could not find the resource file generated by Google Services. You may need to execute the :process<Variant>GoogleServices Task. Please check your Firebase project configuration (https://firebase.google.com/docs/android/setup).
The issue is two years old and it is the highest voted firebase sdk github issue, shouldn't it have a top priority?
we're facing exactly the same problem with mappingFileUploadEnabled
I totally agree, this should have more priority.
Is it possible to set up Firebase Cloud messaging from the instance of the second app ?
We do use messaging successfully from the new app that we switch to.
The issue is two years old and it is the highest voted firebase sdk github issue, shouldn't it have a top priority?
Certainly is top priority :) We'll be sure to share our plans to address this issue with folks on this issue, to get some early feedback.
@ashwinraghav - does this mean a fix on the Android side is close? https://github.com/firebase/firebase-ios-sdk/pull/6142 - Not exactly related but going the right direction.
Google Play console start showing:
Please upgrade to the generally available Firebase Crashlytics SDK to continue receiving crash reports in the Firebase console after 15 November 2020.
We really would like, but it's not possible when we still have no option to log to the correct project :)
Do you have some estimation, when this issue will be resolved? We don't like it when we have just a few days to implement new features until Google kills the old one :). When you have one month releasing window (contracting), you don't have much time...
It was a wonderful time to work with the Fabric, until google bought it. I could init crashlytics, analytics manually when I needed it, but now I can't. Why do I need this - because I want to keep securely all the firebase keys and run firebase, crashlytics, analytics dynamically. But for now I can init the firebase without json file, but crashlytics doesn't work in this case:
Logs when trying to build a release project: FAILURE: Build failed with an exception.
Crashlytics could not find the resource file generated by Google Services. You may need to execute the :process
GoogleServices Task. Please check your Firebase project configuration (https://firebase.google.com/docs/android/setup).
Please rollback to previous build project feature, like it was with Fabric.
Here is a tested workaround, how to to init crashlytics and firebase when you need:
google-services.json file
dependencies {
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
}
// Google Services Gradle plugin
apply plugin: 'com.google.gms.google-services'
// Apply the Crashlytics Gradle plugin
apply plugin: 'com.google.firebase.crashlytics'
<string tools:ignore="UnusedResources,TypographyDashes"
name="com.crashlytics.android.build_id"
translatable="false">*********************</string>
For analytics:
<string name="google_app_id" translatable="false">************</string>
google-services.json file
dependencies {
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
}
// Google Services Gradle plugin
apply plugin: 'com.google.gms.google-services'
// Apply the Crashlytics Gradle plugin
<provider
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:authorities="${applicationId}.firebaseinitprovider"
tools:node="remove"/>
I created a test crash with this solution and found the report in the dashboard.
Workaround when you have generated xml file, but not google-services plugin itself:
val copyGoogleIdValuesTask = tasks.register("copyGoogleIdValues", Copy::class.java) {
from("src/main/res/values/google-services.xml")
into("${project.buildDir}/generated/res/google-services/values.xml")
}
tasks.withType<com.google.firebase.crashlytics.buildtools.gradle.tasks.UploadMappingFileTask>() {
dependsOn(copyGoogleIdValuesTask)
}
May not work in multivariant apps.
Is there any update on this problem wrt. Firebase Analytics, as of September 29th, 2020. I'm having to solve the exact same problem, and I'm out of solutions.
Does anyone else have any other way by which this problem can be solved?
Workaround (groovy syntax) when you have generated xml file located in src/release/res/values/values.xml
task copyGoogleIdValuesTask(type: Copy) {
from 'src/release/res/values/values.xml'
into "$project.buildDir/generated/res/google-services/release/values/"
}
import com.google.firebase.crashlytics.buildtools.gradle.tasks.UploadMappingFileTask
tasks.withType(UploadMappingFileTask).configureEach {
dependsOn(copyGoogleIdValuesTask)
}
Works for release build variant.
Any update on this? Still facing this issue in March of 2021 😩
The @1951FDG workaround works, but if we update to crashlytics gradle plugin 2.7.+ we have this error now: https://github.com/firebase/firebase-android-sdk/issues/2721
Still facing this issue in December of 2021. They resolved 926 issues. But this 66th issue is open for over 3 years. Flutter developers have no idea that this is a native android SDK issue. Because it's working fine for iOS.
Any update on this?
Still no solution for this? March 2022 :(
Hi, we've implemented a workaround for use of Firebase Analytics. We've not tested any other usage. Your milage may vary.
Overview
It appears the actual analytics code is implemented in play-services-measurement-*.jar files (which I assume are downloaded automatically via Google Play Services).
To initialise Firebase I call the following programmatically:
FirebaseOptions.Builder builder = new FirebaseOptions.Builder()
.setApplicationId(FirebaseConstants.APP_ID)
.setApiKey(FirebaseConstants.API_KEY)
.setGcmSenderId(FirebaseConstants.MESSAGING_SENDER_ID)
.setProjectId(FirebaseConstants.PROJECT_ID);
FirebaseApp.initializeApp(getContext(), builder.build());
FirebaseAnalytics.getInstance(getContext());
The context provided by getContext()
is internally converted by Firebase to an application context, which is then cast to an android.app.Application
. The play-services-measurement-* code then calls the application's getResources()
method, followed by a call to Resource.getIdentifier("google_app_id", "string", "<your-package>")
to return the R.string.google_app_id
constant. Then Resource.getString(R.string.google_app_id)
is called to return the actual value you should have declared in strings.xml
(which won't exist as we're trying to do this programmatically).
Implementation
Add the following to your android.app.Application
subclass:
private FirebaseResourcesWrapper firebaseResources;
@Override
public Resources getResources() {
if (firebaseResources == null)
firebaseResources = new FirebaseResourcesWrapper(super.getResources());
return firebaseResources;
}
The FirebaseResourcesWrapper
subclasses android.content.res.Resources
and implements the class wrapper pattern. Here we forward all visible public methods to the original wrapped class, except for getIdentifer()
and getString()
which we override as follows:
public class FirebaseResourcesWrapper extends Resources {
private static final String GOOGLE_APP_ID = "google_app_id";
private static final int R_STRING_GOOGLE_APP_ID = 1_999_999_999;
private final Resources wrapped;
public FirebaseResourcesWrapper(Resources wrapped) {
super(wrapped.getAssets(), wrapped.getDisplayMetrics(), wrapped.getConfiguration());
this.wrapped = wrapped;
}
public int getIdentifier(String name, String defType, String defPackage) {
if (GOOGLE_APP_ID.equals(name) && "string".equals(defType))
return R_STRING_GOOGLE_APP_ID;
return wrapped.getIdentifier(name, defType, defPackage);
}
public String getString(int id) throws NotFoundException {
if (id == R_STRING_GOOGLE_APP_ID)
return FirebaseConstants.APP_ID;
return wrapped.getString(id);
}
public String getString(int id, Object... formatArgs) throws NotFoundException {
return wrapped.getString(id, formatArgs);
}
Full implementation of FirebaseResourcesWrapper.java
in this GitHub gist:
https://gist.github.com/electricbolt/423c03f09bc0303d0d5696b8beb392bd
Any update on this?
Any update on this issue?
👋
Hi @ashwinraghav, have there been any updates on a fix for this issue?
same issue.
Any news on this issue?
Same issue here. 5-6 years later, still no plan to fix it?
Using this workaround seems to work. https://github.com/firebase/firebase-android-sdk/issues/66#issuecomment-1142669342
@sergey-avagyan @Hunter54 Stop waiting, just use FirebaseResourcesWrapper or similar solution. Gооglе never fixes issues, until they become a problem, until it threatens their business.
Hi, we've implemented a workaround for use of Firebase Analytics. We've not tested any other usage. Your milage may vary.
Overview
It appears the actual analytics code is implemented in play-services-measurement-*.jar files (which I assume are downloaded automatically via Google Play Services).
To initialise Firebase I call the following programmatically:
FirebaseOptions.Builder builder = new FirebaseOptions.Builder() .setApplicationId(FirebaseConstants.APP_ID) .setApiKey(FirebaseConstants.API_KEY) .setGcmSenderId(FirebaseConstants.MESSAGING_SENDER_ID) .setProjectId(FirebaseConstants.PROJECT_ID); FirebaseApp.initializeApp(getContext(), builder.build()); FirebaseAnalytics.getInstance(getContext());
The context provided by
getContext()
is internally converted by Firebase to an application context, which is then cast to anandroid.app.Application
. The play-services-measurement-* code then calls the application'sgetResources()
method, followed by a call toResource.getIdentifier("google_app_id", "string", "<your-package>")
to return theR.string.google_app_id
constant. ThenResource.getString(R.string.google_app_id)
is called to return the actual value you should have declared instrings.xml
(which won't exist as we're trying to do this programmatically).Implementation
Add the following to your
android.app.Application
subclass:private FirebaseResourcesWrapper firebaseResources; @Override public Resources getResources() { if (firebaseResources == null) firebaseResources = new FirebaseResourcesWrapper(super.getResources()); return firebaseResources; }
The
FirebaseResourcesWrapper
subclassesandroid.content.res.Resources
and implements the class wrapper pattern. Here we forward all visible public methods to the original wrapped class, except forgetIdentifer()
andgetString()
which we override as follows:public class FirebaseResourcesWrapper extends Resources { private static final String GOOGLE_APP_ID = "google_app_id"; private static final int R_STRING_GOOGLE_APP_ID = 1_999_999_999; private final Resources wrapped; public FirebaseResourcesWrapper(Resources wrapped) { super(wrapped.getAssets(), wrapped.getDisplayMetrics(), wrapped.getConfiguration()); this.wrapped = wrapped; } public int getIdentifier(String name, String defType, String defPackage) { if (GOOGLE_APP_ID.equals(name) && "string".equals(defType)) return R_STRING_GOOGLE_APP_ID; return wrapped.getIdentifier(name, defType, defPackage); } public String getString(int id) throws NotFoundException { if (id == R_STRING_GOOGLE_APP_ID) return FirebaseConstants.APP_ID; return wrapped.getString(id); } public String getString(int id, Object... formatArgs) throws NotFoundException { return wrapped.getString(id, formatArgs); }
Full implementation of
FirebaseResourcesWrapper.java
in this GitHub gist:https://gist.github.com/electricbolt/423c03f09bc0303d0d5696b8beb392bd
Thanks for your solution. I've got one question, how do you define FirebaseConstants? In my app, while initializing flutter app I pull secrets from secrets manager, save it in FlutterSecureStorage and initialize FirebaseApplication with appropriate secrets pulled in previous step. Firestore and crashlytics work fine, but analytics don't. The solution proposed by you looks promising, but I'm missing one part, how to share these secrets in FirebaseResourcesWrapper class. I would be grateful if you could share your ideas!
[REQUIRED] Step 3: Describe the problem
I am trying to initialize the FirebaseApp, only by using the FirebaseOptions builder, like this, first thing in my application (I use only applicationId and ApiKey, since I only want the analytics for start) :
I do not have a google-services.json file in my project, I have removed the FirebaseInitProvider, like this, in my AndroidManifest.xml:
When starting the application, while trying to View events in the Android Studio debug log, like this: adb shell setprop log.tag.FA VERBOSE adb shell setprop log.tag.FA-SVC VERBOSE adb logcat -v time -s FA FA-SVC
I get Missing google_app_id. Firebase Analytics disabled. See https://goo.gl/NAOOOI .