Реализация Firebase внутри библиотеки

Я хочу внедрить систему уведомлений Friebase внутри библиотеки, которую я хочу использовать в качестве SDK во многих приложениях.

Firebase теперь запрашивает идентификатор приложения, но я реализую его внутри библиотеки, поэтому идентификатор приложения не указан.

Как я могу достичь своей цели, чтобы иметь возможность отправлять уведомления в мои приложения, которые используют мою библиотеку?

Заранее спасибо.

 Steven Scott26 июл. 2016 г., 20:31
Я бы так подумал, передав идентификатор приложения в библиотеку через инициализацию библиотеки из вашего основного приложения.
 Joaquim Ley17 авг. 2016 г., 18:14
Эй, @Sekai, если мой ответ решил твою проблему, отметьте его как принятый (политика SO)

Ответы на вопрос(5)

Решение Вопроса

Да, вы можете сделать это в своей библиотекеbuild.gradle поместите это в поле defaultConfig

buildConfigField("String", "FIREBASE_APP_KEY", "\"${firebaseAppKey}\"")

Тогда внутри вашего проектаgradle.properties

firebaseAppKey = <yourFirebaseAppSecret>;

Закаждый проект / приложение, вы должны определить эту переменную на вашемgradle.properties.

Вам нужно будет создать приложение Firebase для каждого проекта., но ваша библиотека теперь может иметь Firebase SDK.

Если вы хотите получить доступ к этому значению переменной среды, используйтеBuildConfig.FIREBASE_APP_KEY (например, создать экземпляр Firebase).

 Joaquim Ley07 авг. 2016 г., 11:33
@ Seekai Я думаю, что настройка только файлов gradle вполне приемлема. Если вы предварительно настроите свою библиотеку таким образом, я как разработчик был бы весьма рад. Единственное, что нужно сделать вашему «клиенту», - это создать свое собственное приложение Firebase (никак не обойтись) и использовать свой собственный ключ, таким образом, ключ нигде не будет открыт, если вы не загружаете свойgradle.properties (что вы не должны).
 Sekai07 авг. 2016 г., 10:45
Я надеялся на решение, которое требует минимальных манипуляций со стороны разработчиков. Мы попробуем это, и если это не сработает, мы попробуем реализовать уведомления сокетов.

Я знаю, что это старый вопрос с принятым ответом, но у всех ответов есть большое неудобство - они требуют, чтобы пользователь вашей библиотеки выполнял работу помимо добавления вашей библиотеки в свое приложение. Есть способ сделать этоне беспокоя пользователя вашей библиотеки вообще если ваша библиотека загружается из репозитория Maven.

Примечание: этот метод взломан и не поддерживается Firebase. Когда я спросил Firebase Support, я получил следующий ответ:

Firebase SDK не предназначены для библиотечных проектов, Функции, доступные в Firebase, были интегрированы на уровне приложения, а не для отдельных модулей или библиотек, поэтому сценарий использования для интеграции этого в библиотечный проект невозможен или не поддерживается.

Тем не менее, я нашел способ сделать это, и кто-нибудь найдет это полезным, так что вот оно:

Это пример использования базы данных реального времени, но он должен работать для всех Firebase SDK.

В главном проектеbuild.gradle добавить mavenCentral репозиторий:

allprojects {
    repositories {
        ...
        mavenCentral()
    }
}

В вашей библиотеке проектаbuild.gradle, добавьте Google Play Services (как зависимость, а не как плагин):

compile 'com.google.android.gms:play-services-gcm:11.0.4'

Добавьте соответствующие Firebase SDK (с той же версией, что и у Google Play Services):

compile 'com.google.firebase:firebase-core:11.0.4'
compile 'com.google.firebase:firebase-database:11.0.4'

Зарегистрируйте свой SDK как проект на Firebas, скачайте егоgoogle-services.json и откройте его в любом текстовом редакторе.

В вашей библиотекеstrings.xml добавить следующие строки и заполнить эти строки данными изgoogle-services.json

<string name="gcm_defaultSenderId">project_number</string>
<string name="google_api_key">current_key</string>
<string name="google_app_id">mobilesdk_app_id</string>
<string name="google_crash_reporting_api_key">current_key</string>
<string name="google_storage_bucket">storage_bucket</string>
<string name="firebase_database_url">firebase_url</string>
<string name="default_web_client_id">client_id</string>
<string name="project_id">project_id</string>

Это оно. Вы можете использовать базу данных Firebase Realtime в своей библиотеке, затем собрать ее и опубликовать в Maven (публикация в Maven необходима, в противном случае пользователь вашей библиотеки должен будет добавить зависимости вручную). При активации из приложения ваша база данных будет использоваться.

Обратите внимание, что этот метод может вызвать исключения и неожиданное поведение, если пользователь вашей библиотеки будет использовать Google Play Services или Firebase, поэтомуИспользуйте на свой риск!

 Alix22 февр. 2019 г., 16:08
Я попробовал это, используя последние библиотеки (gcm 16.0.0, firebase-core 16.0.7). Это не работает. Получение «По умолчанию FirebaseApp не удалось инициализировать, так как не было найдено ни одной опции по умолчанию. Обычно это означает, что com.google.gms: google-services не был применен к вашему gradle-проекту». и "Отсутствует google_app_id. Аналитика Firebase отключена." даже если добавить такие строки как в библиотеку, так и в приложение. Похоже, что это невозможно сделать без регистрации приложения в Firebase.

Насколько я знаю, ты не можешь.

Каждый проект Firebase нуждается в идентификаторах пакетов, чтобы однозначно идентифицировать каждое из его приложений.

Вам также необходимо настроить каждый модуль со своимgoogle-services.json, который генерируется специально для каждого идентификатора.

В случае, если вы можете использовать один и тот же пакет для всех своих приложений, устройство или сам Play Store не смогут отличить одно от другого, поэтому это не вариант.

Вы можете извлечь всю логику Firebase в свою библиотеку, но все же вам нужно будет настроить каждое приложение для предоставления уникального идентификатора пакета, и вам также необходимо будет отправить уведомление каждому идентификатору.

Все это отчасти хакерская или слишком большая работа, вот хороший и простой пример (хотя иронично, потому что это длинный пост - но оно того стоит).

Можно использоватьFireBase код в вашем проекте библиотеки, конечно, приложение-потребитель должно будет зарегистрировать приложение и получить идентификатор приложения /google-services.json файл.

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

Вот краткий пример использованияfirebase-messaging модуль внутри библиотечного проекта.

Build.gradle модуля YourLibrary:

// Other typical library set up 
apply plugin: 'com.android.library'

android {
    compileSdkVersion 27

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName '1.0'

        // Don’t for get your library’s proguard file!
        consumerProguardFiles 'proguard-rules.pro'
    }
}

ext {
    currentFirebaseVersion = "11.8.0"
}

dependencies {
    /* 
    Here we depend on the firebase messaging dependency (via compileOnly),
    allowing us to use the FireBase API within our library module.

    I exclude that org.json module because it may cause build warnings, this 
    step isn’t totally necessary.

    NOTE: You should use `compileOnly` here so the dependency is
    not added to the build output You will be allowed to use the 
    dependency in your library. If the consuming app wants to use firebase
    they’ll need to depend on it (using `implementation`).
    */
    compileOnly("com.google.firebase:firebase-messaging:$currentFirebaseVersion") {
        exclude group: 'org.json', module: 'json'
    }
}

// Other typical library set up. But nothing else relating Firebase.

Это все, что вам нужно сделать в вашем проекте библиотеки.НЕ примените здесь плагин gms ине добавить путь к классам google-services в библиотекиbuild.gradle.

Теперь вот как вы настроили ваше приложение-потребитель:

MyClientApp верхнего уровня build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        google() // You know the drill...
    }
    // Any other set up you might have...

    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        /*
        Here in your client app’s top-level build.gradle you add the
        google-services to the app’s classpath.
        */
        classpath 'com.google.gms:google-services:3.2.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
// Other basic stuff...
allprojects {
    apply plugin: 'maven'
    apply plugin: 'maven-publish'

    repositories {
        jcenter()
        google()
    }
}

Теперь нам нужно настроить модуль приложений-потребителейbuild.gradle, это просто. Нам просто нужно применить плагин, и мы зависим от модуля библиотеки, который мы создаем, который имеет всеFireBase код в нем.

Уровень модуля MyClientApp build.gradle:

buildscript {
    repositories {
        google()
        mavenLocal()
    }
}
apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.your.application.that.can.use.firebase"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName '1.0'
    }
    //other typical set up
}

ext {
    currentFirebaseVersion = "11.8.0"
}

dependencies {
    implementation('com.your.library:YourLibrary:[email protected]') {
        transitive = true
        // Use the consuming application's FireBase module, so exclude it
        // from the dependency. (not totally necessary if you use compileOnly
        // when declaring the dependency in the library project).
        exclude group: 'com.google.firebase'
        // Exclude the "plain java" json module to fix build warnings.
        exclude group: 'org.json', module: 'json'
    }

    implementation("com.google.firebase:firebase-messaging:$currentFirebaseVersion") {
        // Exclude the "plain java" json module to fix build warnings.
        exclude group: 'org.json', module: 'json'
    }
}

// Needs to be at the bottom of file.
apply plugin: 'com.google.gms.google-services'

Некоторые вещи, на которые стоит обратить внимание:

Нужно применить плагин google-services внизу (только в клиентском модулеbuild.gradle).Зависит от модуля библиотеки, который имеетFireBase код в нем, но исключить его версиюFireBase модуль, в пользу вашей собственной версии зависимости.Приложение зависит от его собственногоFireBase версия.classpath 'com.google.gms:google-services:3.1.1’ входит только в верхний уровень клиентского приложенияbuild.gradle.Конечно, вам нужно будет зарегистрировать клиентское приложение и поставитьgoogle-services.json в проекте вашего клиентского приложения.Определите необходимоеFirebase Serviceв манифесте вашего приложения (или используйте слияние манифеста и объедините их из вашего библиотечного проекта)Добавитьgoogle_play_services_version тег метаданных в манифест вашего клиентского приложения.Библиотека может / должна использоватьcompileOnly при объявленииFireBase зависимость.

Теперь вы сможете использоватьFireBase код в вашем приложении, который вы определили в вашей библиотеке, которая используетFireBase, Или вы можете позволить вашему библиотечному модулю делать всеFireBase Работа!

Конечно, это обычно используется для внутренних библиотек, таких какFirebase не были предназначены для реализации в библиотечных модулях, но иногда это необходимо, так что это простое не хакерское / вменяемое решение проблемы. Его можно использовать в проектах, распространяемых через maven - моя библиотека использует это, и это никогда не вызывало никаких проблем.

Обновить:

Вы должны использоватьcompileOnly при объявлении модуля библиотекиFirebase зависимость. Таким образом, зависимость не будет добавлена ​​к выводу сборки. Но вам будет разрешено использовать зависимость в вашей библиотеке. Если приложение-потребитель хочет использовать firebase, оно должно зависеть от него вручную (используяimplementation). Это поможет сократить ненужные зависимости / раздувание в приложениях и «правильный» способ объявить такую ​​зависимость.Замечания: Вам может потребоваться выполнить проверки во время выполнения, чтобы убедиться, что библиотека доступна, прежде чем использовать ее код в вашем модуле.

 sasha_trn03 июн. 2018 г., 20:58
Спасибо за решение. Некоторые заметки. У меня была проблема сclasspath 'com.google.gms:google-services:4.0.0', я получилCould not find google-services.json while looking in [src/nullnull/debug, src/debug/nullnull, src/nullnull, src/debug, src/nullnullDebug] registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection) Пришлось откатиться до версии 3.2.1. Затем было скомпилировано.

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

Ваш ответ на вопрос