Можно ли инициализировать Firebase без использования google-services.json?

EDIT: Я должен подчеркнуть, что у меня есть вкусы, для которых я не хочу использовать какие-либо из этих сервисов Google и пытаюсь применить плагин google-services в таком случае, не имея соответствующих сервисов Google. json, приведет к сбою сборки.

Я хотел бы иметь возможность инициализировать Firebase SDK, в частности, использовать Remote Config, БЕЗ использования google-services.json.

Я вижу, что FirebaseApp имеет метод initialize, который получает объект FirebaseOptions.

Я создал FirebaseOptions со значениями, указанными в google-services.json, и после вызова FirebaseApp.initialize с этими параметрами я всегда получаю

FirebaseInitProvider: FirebaseApp initialization unsuccessful

Я знаю, что это рекомендуемый способ использования файла google-services.json, но мне нужно, чтобы приложение вызывало различные проекты Firebase, в зависимости от сборки debug/release, сохраняя имя пакета одинаковым.

То, как я хотел бы сделать это, - это иметь пары отладки/выпуска для всех значений, необходимых для инициализации Firebase, а затем динамически выполнять инициализацию.

        FirebaseOptions options = new FirebaseOptions.Builder()
                .setApplicationId(appId)
                .setApiKey(apiKey)
                .setGcmSenderId(appContext.getString(
                        isDebug ? R.string.firebase_testing_gcm_sender_id :
                                R.string.firebase_production_gcm_sender_id))
                .setDatabaseUrl(appContext.getString(
                        isDebug ? R.string.firebase_testing_database_url :
                                R.string.firebase_production_database_url))
                .setStorageBucket(
                        appContext.getString(
                                isDebug ? R.string.firebase_testing_storage_bucket :
                                        R.string.firebase_production_storage_bucket))
                .build();
        FirebaseApp.initializeApp(appContext, options);

Пока это не работает.

Вся помощь очень ценится!

Ответ 1

Вот пара советов о том, как использовать несколько приложений/баз данных Firebase в одном проекте Android Firebase Blog и New Config Docs

Однако они говорят об использовании дополнительного приложения в дополнение к приложению по умолчанию, которое все еще использует google-services.json. Я провел небольшое исследование и изучил их канал Slack. Firebase использует ContentProvider с именем FirebaseInitProvider. Он использует google-services.json для инициализации приложения DEFAULT при запуске. Это barfs, если файл json отсутствует. Я сделал следующие шаги:

  • Удален google-services.json
  • Удален плагин com.google.gms.google-services. Этот плагин всегда ищет файл JSON.
  • FirebaseInitProvider добавляется путем слияния манифеста. Однако в манифесте верхнего уровня вы можете указать тег node = remove, чтобы удалить его из окончательного манифеста.

    <provider android:authorities="${applicationId}.firebaseinitprovider"
        android:name="com.google.firebase.provider.FirebaseInitProvider" 
        android:exported="false"
        tools:node="remove"/>
    

Однако даже после этого я все еще вижу исключение:

java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process myfirebasedemo.net. Make sure to call FirebaseApp.initializeApp(Context) first.
                                                                 at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
                                                                 at com.google.firebase.iid.FirebaseInstanceId.getInstance(Unknown Source)
                                                                 at com.google.firebase.iid.FirebaseInstanceIdService.zza(Unknown Source)
                                                                 at com.google.firebase.iid.FirebaseInstanceIdService.zzm(Unknown Source)
                                                                 at com.google.firebase.iid.zzb$2.run(Unknown Source)
                                                                 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                 at java.lang.Thread.run(Thread.java:818)

Похоже, FirebaseInstanceIdService по-прежнему ищет экземпляр приложения. Если вы отключите службу, используя тот же метод удаления узла манифеста, то это исключение исчезнет. Но я думаю, что эта служба выполняет важные функции синхронизации/обмена сообщениями. Так что не уверен, стоит ли удалять это. Короче говоря - я все еще ищу идеальное решение для отключения приложения по умолчанию/без использования google-services.json. Любые дальнейшие указатели будут высоко оценены.

ОБНОВИТЬ:

Похоже, что это решение работает в конце концов - не отключая FirebaseInstanceIdService и просто удаляя FirebaseInitProvider, как упомянуто выше. Просто нужно убедиться, что Firebase.initializeApp первым вызвал метод Application :: onCreate.

FirebaseApp.initializeApp(context, new FirebaseOptions.Builder().setApiKey("<VAL>").
                    setApplicationId("<VAL>").
                    setDatabaseUrl("<VAL>").
                    setGcmSenderId("<VAL>").
                    setStorageBucket("<VAL>").build());  

Ответ 2

Я нашел интересное обходное решение. Попробуйте следующее: поместите ваш google-services.json в любое образцовое приложение google предоставляет для интеграции Firebase. Скомпилируйте его.

Посмотрите на путь app/build/generated/res/google-services/debug/values/ должен быть сгенерирован файл values.xml с кучей строк, упомянутых в описанных вами ошибках. Скопируйте эти строки в файл value.xml вашего проекта. Что это.

Ответ 3

Я также использую варианты сборки для применения различных конфигураций для разных сред. У меня была та же проблема, что и некоторые из вариантов не имели соответствующей записи в файле google-services.json. что привело к сбою некоторых из моих сборок при создании пакета приложения, который не был настроен в firebase.

Моим обходным путем для этого было добавить фиктивные записи приложений для недостающих пакетов в соответствующих проектах firebase на панели управления firebase, а затем получить от него обновленный файл google-services.json.

Не может быть лучшей практики, но я сделал это в своем случае.

Ответ 4

google-services.json является обязательным и предназначен для удобства. Так что если вы находите это неудобным, то определенно не используйте его.

Как вы могли заметить, файл json используется только во время сборки. Плагин google-services превращает файл JSON в файл ресурсов xml содержащий некоторые конкретные строки. Это выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <! -- Present in all applications -->
    <string name="google_app_id" translatable="false">1:1035469437089:android:73a4fb8297b2cd4f</string>

    <! -- Present in applications with the appropriate services configured -->
    <string name="gcm_defaultSenderId" translatable="false">1035469437089</string>
    <string name="default_web_client_id" translatable="false">337894902146-e4uksm38sne0bqrj6uvkbo4oiu4hvigl.apps.googleusercontent.com</string>
    <string name="ga_trackingId" translatable="false">UA-65557217-3</string>
    <string name="firebase_database_url" translatable="false">https://example-url.firebaseio.com</string>
    <string name="google_api_key" translatable="false">AIzbSyCILMsOuUKwN3qhtxrPq7FFemDJUAXTyZ8</string>
    <string name="google_crash_reporting_api_key" translatable="false">AIzbSyCILMsOuUKwN3qhtxrPq7FFemDJUAXTyZ8</string>
    <string name="project_id" translatable="false">mydemoapp</string>

</resources>

Вы можете просто создать эти записи в своем собственном файле strings.xml а затем FirebaseApp.initializeApp() найдет их во время выполнения. Не все ключи требуются, это зависит от того, какой сервис вы используете. Например, почти все сервисы требуют ключ google_app_id. Firestore нужен только этот и project_id, в то время как Firebase Auth также нужен google_api_key. Не должно быть слишком сложно экспериментировать и выяснить, какие из них вам нужны.

Некоторые ссылки: