Я купил шаблон приложения, и я не могу понять в коде, где изменить заголовок и содержимое уведомления pu sh (Firebase в качестве платформы поставщика сообщений). Разработчик недоступен, и я не могу go дальше с проектом.
Например, вместо pu sh «У вас есть новое сообщение» Я хочу, чтобы «У вас было ОДНО новое сообщение»; Я безуспешно искал весь код.
Кроме того, есть ли способ, чтобы уведомления pu sh могли быть переведены на несколько языков?
Редактировать
В исходном файле отсутствует служба расширения Firebase, связанная с обменом сообщениями, только для проверки подлинности телефона.
Пример кода:
package com.innomalist.taxi.driver.activities.splash
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.WindowManager
import androidx.databinding.DataBindingUtil
import com.crashlytics.android.Crashlytics
import com.firebase.ui.auth.AuthUI
import com.firebase.ui.auth.AuthUI.IdpConfig.PhoneBuilder
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.iid.FirebaseInstanceId
import com.gun0912.tedpermission.PermissionListener
import com.gun0912.tedpermission.TedPermission
import com.innomalist.taxi.common.components.BaseActivity
import com.innomalist.taxi.common.interfaces.AlertDialogEvent
import com.innomalist.taxi.common.networking.socket.interfaces.ConnectionError
import com.innomalist.taxi.common.networking.socket.interfaces.Namespace
import com.innomalist.taxi.common.networking.socket.interfaces.RemoteResponse
import com.innomalist.taxi.common.networking.socket.interfaces.SocketNetworkDispatcher
import com.innomalist.taxi.common.utils.AlertDialogBuilder
import com.innomalist.taxi.common.utils.AlertDialogBuilder.DialogResult
import com.innomalist.taxi.common.utils.AlertDialogBuilder.show
import com.innomalist.taxi.common.utils.AlerterHelper.showError
import com.innomalist.taxi.common.utils.CommonUtils.isGPSEnabled
import com.innomalist.taxi.common.utils.CommonUtils.isInternetDisabled
import com.innomalist.taxi.common.utils.MyPreferenceManager.Companion.getInstance
import com.innomalist.taxi.driver.R
import com.innomalist.taxi.driver.activities.main.MainActivity
import com.innomalist.taxi.driver.activities.profile.ProfileActivity
import com.innomalist.taxi.driver.databinding.ActivitySplashBinding
import com.innomalist.taxi.driver.networking.http.GetRegisterInfo
import com.innomalist.taxi.driver.networking.http.Login
import com.innomalist.taxi.driver.networking.http.LoginResult
import com.innomalist.taxi.driver.networking.http.RegistrationInfo
import io.fabric.sdk.android.Fabric
import java.lang.Exception
class SplashActivity : BaseActivity() {
private lateinit var binding: ActivitySplashBinding
private var SIGN_IN_ACTIVITY = 123
private var startRequested = false
private val permissionListener: PermissionListener = object : PermissionListener {
override fun onPermissionDenied(deniedPermissions: List<String>) {
show(this@SplashActivity,"It is not possible to run the app as driver without location permission. Given that you have already didn't approved location access you can now go to settings and enabled it. Then you can close app and open it again to access.", AlertDialogBuilder.DialogButton.OK, AlertDialogEvent {
checkPermissions()
})
}
override fun onPermissionGranted() {
if(getInstance(applicationContext).token != null) {
tryConnect(getInstance(applicationContext).token!!)
} else {
goToLoginMode()
}
}
}
private val onLoginClicked = View.OnClickListener {
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(listOf(PhoneBuilder().build()))
.setLogo(R.drawable.logo)
.setTheme(currentTheme)
.build(),
SIGN_IN_ACTIVITY)
}
override fun onCreate(savedInstanceState: Bundle?) {
isImmersive = true
super.onCreate(savedInstanceState)
if (getString(R.string.fabric_key) != "") {
Fabric.with(this, Crashlytics())
}
requestWindowFeature(Window.FEATURE_NO_TITLE)
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
binding = DataBindingUtil.setContentView(this, R.layout.activity_splash)
binding.loginButton.setOnClickListener(onLoginClicked)
checkPermissions()
}
private fun checkPermissions() {
if (!isGPSEnabled(this)) {
show(this, getString(R.string.message_enable_gps), AlertDialogBuilder.DialogButton.CANCEL_RETRY, AlertDialogEvent { result: DialogResult ->
if (result === DialogResult.RETRY) {
checkPermissions()
} else {
finishAffinity()
}
})
return
}
if (isInternetDisabled(this)) {
show(this, getString(R.string.message_internet_connection), AlertDialogBuilder.DialogButton.CANCEL_RETRY, AlertDialogEvent { result: DialogResult ->
if (result === DialogResult.RETRY) {
checkPermissions()
} else {
finishAffinity()
}
})
return
}
TedPermission.with(this)
.setPermissionListener(permissionListener)
.setDeniedMessage(getString(R.string.message_permission_denied))
.setPermissions(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
.check()
}
fun tryConnect(jwtToken: String) {
FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener {fb ->
SocketNetworkDispatcher.instance.connect(Namespace.Driver, jwtToken, fb.result?.token ?: "") {
when (it) {
is RemoteResponse.Success -> {
startMainActivity()
}
is RemoteResponse.Error -> {
when (it.error) {
ConnectionError.RegistrationIncomplete -> {
runOnUiThread {
showRegisterForm(jwtToken)
}
}
else -> {
runOnUiThread {
goToLoginMode()
try {
it.error.showAlert(this)
} catch (exception: Exception) {
}
}
}
}
}
}
}
}
}
private fun showRegisterForm(jwtToken: String) {
GetRegisterInfo(jwtToken).execute<RegistrationInfo> {
when(it) {
is RemoteResponse.Success -> {
runOnUiThread {
preferences.driver = it.body.driver
preferences.services = ArrayList(it.body.services)
val intent = Intent(this@SplashActivity, ProfileActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
}
}
is RemoteResponse.Error -> {
//it.error.showAlert(this)
}
}
}
}
override fun onResume() {
super.onResume()
if(preferences.token != null) {
tryConnect(preferences.token!!)
}
}
private fun startMainActivity() {
if (startRequested) return
startRequested = true
val intent = Intent(this@SplashActivity, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
}
private fun tryLogin(firebaseToken: String) {
goToLoadingMode()
Login(firebaseToken).execute<LoginResult> {
when(it) {
is RemoteResponse.Success -> {
getInstance(applicationContext).driver = it.body.user
getInstance(applicationContext).token = it.body.token
tryConnect(it.body.token)
}
is RemoteResponse.Error -> {
showError(this, it.error.localizedDescription)
}
}
}
}
private fun goToLoadingMode() {
binding.loginButton.visibility = View.GONE
binding.progressBar.visibility = View.VISIBLE
}
private fun goToLoginMode() {
binding.loginButton.visibility = View.VISIBLE
binding.progressBar.visibility = View.GONE
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SIGN_IN_ACTIVITY) {
if (resultCode == Activity.RESULT_OK) {
FirebaseAuth.getInstance().currentUser!!.getIdToken(false).addOnCompleteListener {
tryLogin(it.result!!.token!!)
}
return
}
showError(this@SplashActivity, getString(R.string.login_failed))
goToLoginMode()
}
}
}
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ
Позвольте мне объяснить вам природу сообщения: есть ДВА приложения - водитель и пассажир: когда пассажир что-то делает, например - спрашивает возле водителя, все водители поблизости получают pu sh сообщение - у вас есть один новый запрос. Также, например, при совершении платежа пассажир получает сообщение - оплата произведена. Где это хранится, ради бога:)
GRADLE FILES
В приложении есть ТРИ модуля - общие, драйвер и райдер и четыре файла gradle.build.
Общий модуль Gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
multiDexEnabled true
versionCode 1
versionName '1.0.0'
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled true
}
}
dependencies {
api 'androidx.multidex:multidex:2.0.1'
api 'androidx.recyclerview:recyclerview-selection:1.1.0-beta01'
api 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
api 'com.google.android.material:material:1.2.0-alpha03'
api 'com.google.android.gms:play-services-maps:17.0.0'
api 'com.google.android.gms:play-services-location:17.0.0'
api 'com.google.firebase:firebase-messaging:20.1.0'
api 'com.firebaseui:firebase-ui:6.2.0'
api('io.socket:socket.io-client:1.0.0') {
exclude group: 'org.json', module: 'json'
}
api('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') {
transitive = true
}
api 'com.google.maps.android:android-maps-utils:0.6.2'
api 'com.github.medyo:android-about-page:1.2.4'
api 'com.squareup.moshi:moshi:1.9.2'
api 'com.squareup.moshi:moshi-kotlin:1.9.2'
kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.9.2'
api 'de.psdev.licensesdialog:licensesdialog:2.1.0'
api 'com.github.tylersuehr7:empty-state-recyclerview:1.0.4'
api 'com.github.yalantis:ucrop:2.2.4'
api 'com.github.esafirm.android-image-picker:imagepicker:2.2.0'
api 'com.github.bumptech.glide:glide:4.10.0'
api 'com.tapadoo.android:alerter:5.0.0'
api 'gun0912.ted:tedpermission:2.2.2'
api 'com.github.stfalcon:chatkit:0.3.3'
api('com.stripe:stripe-android:12.8.2@aar') {
transitive = true
}
api 'com.github.MAXDeliveryNG:slideview:1.1.0'
api 'com.braintreepayments.api:drop-in:3.7.1'
api 'com.airbnb.android:lottie:3.3.1'
//noinspection LifecycleAnnotationProcessorWithJava8
kapt 'androidx.lifecycle:lifecycle-compiler:2.2.0'
api 'androidx.preference:preference-ktx:1.1.0'
api 'androidx.core:core-ktx:1.1.0'
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
api "org.jetbrains.kotlin:kotlin-script-runtime:1.3.61"
api 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
api 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
}
Драйвер модуля Gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'io.fabric'
android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
defaultConfig {
applicationId 'com.ldrive.taxi.driver'
minSdkVersion 19
targetSdkVersion 29
versionCode 35
versionName '3.0.9'
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
api project(':common')
api 'com.diogobernardino:williamchart:3.3.0'
}
apply plugin: 'com.google.gms.google-services'
repositories {
mavenCentral()
}
Пассажирский / пассажирский модуль Gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'io.fabric'
android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
defaultConfig {
applicationId "com.ldrive.taxi.rider"
minSdkVersion 19
targetSdkVersion 29
multiDexEnabled true
versionCode 35
versionName "3.0.9"
vectorDrawables.useSupportLibrary = true
dexOptions {
jumboMode true
}
}
if (project.hasProperty("RELEASE_KEY_ALIAS")) {
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
api project(':common')
implementation 'com.github.Innomalist:floatingsearchview:0.3'
implementation ('com.google.android.libraries.places:places:2.1.0')
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
testImplementation 'junit:junit:4.12'
}
configurations {
all*.exclude group: 'com.google.guava', module: 'listenablefuture'
}
apply plugin: 'com.google.gms.google-services'
GRADLE ПРОЕКТА
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.61'
repositories {
maven { url "https://maven.google.com" }
jcenter()
maven { url 'https://maven.fabric.io/public' }
google()
maven { url 'https://plugins.gradle.org/m2/'}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'io.fabric.tools:gradle:1.29.0'
classpath 'com.google.gms:google-services:4.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
maven { url "https://maven.google.com" }
jcenter()
mavenCentral()
google()
maven { url "https://jitpack.io" }
maven { url 'https://maven.fabric.io/public' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}