it-roy-ru.com

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

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

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

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

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

20
Sekai

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

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

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

firebaseAppKey = <yourFirebaseAppSecret>;

Для каждого project/app вы должны определить эту переменную в своем gradle.properties

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

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

9
Joaquim Ley

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

5
Arthur Thompson

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

Можно использовать код 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 в проект вашего клиентского приложения.
  • Определите необходимые FirebaseServices в манифесте вашего приложения (или используйте слияние манифеста и объедините их из вашего библиотечного проекта)
  • Добавьте тег метаданных google_play_services_version в манифест вашего клиентского приложения.
  • Библиотека может/должна использовать compileOnly при объявлении зависимости FireBase.

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

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

Обновление:  

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

5
Sakiboy

Я знаю, что это старый вопрос с принятым ответом, но все ответы имеют большое неудобство - они требуют, чтобы пользователь вашей библиотеки выполнял свою работу помимо добавления вашей библиотеки в свое приложение. Есть способ сделать это вообще не беспокоить пользователя вашей библиотеки если ваша библиотека загружается из репозитория 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 или Firebase, поэтому используйте на свой страх и риск!

4
Sir Codesalot

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

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

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

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

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

0
josemigallas