mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-07 21:37:02 +09:00
DROID-3636 Notifications | Firebase messaging service implementation (#2383)
This commit is contained in:
parent
0e9a997998
commit
01638ff2f7
26 changed files with 273 additions and 10 deletions
|
@ -230,6 +230,9 @@ dependencies {
|
|||
|
||||
implementation libs.room
|
||||
|
||||
implementation platform(libs.firebaseBom)
|
||||
implementation libs.firebaseMessaging
|
||||
|
||||
implementation libs.exoPlayerCore
|
||||
implementation libs.exoPlayerUi
|
||||
|
||||
|
|
|
@ -160,6 +160,13 @@
|
|||
</intent-filter>
|
||||
<meta-data android:name="photopicker_activity:0:required" android:value="" />
|
||||
</service>
|
||||
<service
|
||||
android:name="com.anytypeio.anytype.device.AnytypePushService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.anytypeio.anytype.device
|
||||
|
||||
import com.anytypeio.anytype.app.AndroidApplication
|
||||
import com.anytypeio.anytype.domain.device.DeviceTokenStoringService
|
||||
import com.google.firebase.messaging.FirebaseMessagingService
|
||||
import com.google.firebase.messaging.RemoteMessage
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
class AnytypePushService : FirebaseMessagingService() {
|
||||
|
||||
@Inject
|
||||
lateinit var deviceTokenSavingService: DeviceTokenStoringService
|
||||
|
||||
init {
|
||||
Timber.d("AnytypePushService initialized")
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
(application as AndroidApplication).componentManager.pushContentComponent.get().inject(this)
|
||||
super.onCreate()
|
||||
}
|
||||
|
||||
override fun onNewToken(token: String) {
|
||||
super.onNewToken(token)
|
||||
Timber.d("New token received: $token")
|
||||
deviceTokenSavingService.saveToken(token)
|
||||
}
|
||||
|
||||
override fun onMessageReceived(message: RemoteMessage) {
|
||||
super.onMessageReceived(message)
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@ import com.anytypeio.anytype.di.feature.multiplayer.DaggerRequestJoinSpaceCompon
|
|||
import com.anytypeio.anytype.di.feature.multiplayer.DaggerShareSpaceComponent
|
||||
import com.anytypeio.anytype.di.feature.multiplayer.DaggerSpaceJoinRequestComponent
|
||||
import com.anytypeio.anytype.di.feature.notifications.DaggerNotificationComponent
|
||||
import com.anytypeio.anytype.di.feature.notifications.DaggerPushContentComponent
|
||||
import com.anytypeio.anytype.di.feature.objects.DaggerSelectObjectTypeComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingComponent
|
||||
import com.anytypeio.anytype.di.feature.onboarding.DaggerOnboardingStartComponent
|
||||
|
@ -1137,6 +1138,12 @@ class ComponentManager(
|
|||
.create(params, findComponentDependencies())
|
||||
}
|
||||
|
||||
val pushContentComponent = Component {
|
||||
DaggerPushContentComponent
|
||||
.factory()
|
||||
.create(findComponentDependencies())
|
||||
}
|
||||
|
||||
class Component<T>(private val builder: () -> T) {
|
||||
|
||||
private var instance: T? = null
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.anytypeio.anytype.di.feature.notifications
|
||||
|
||||
import com.anytypeio.anytype.device.AnytypePushService
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.domain.device.DeviceTokenStoringService
|
||||
import dagger.Component
|
||||
import dagger.Module
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Component(
|
||||
dependencies = [PushContentDependencies::class],
|
||||
modules = [PushContentModule::class],
|
||||
)
|
||||
interface PushContentComponent {
|
||||
@Component.Factory
|
||||
interface Factory {
|
||||
fun create(dependency: PushContentDependencies): PushContentComponent
|
||||
}
|
||||
|
||||
fun inject(service: AnytypePushService)
|
||||
}
|
||||
|
||||
@Module
|
||||
object PushContentModule {
|
||||
|
||||
}
|
||||
|
||||
interface PushContentDependencies : ComponentDependencies {
|
||||
fun deviceTokenSavingService(): DeviceTokenStoringService
|
||||
}
|
|
@ -8,6 +8,7 @@ import com.anytypeio.anytype.data.auth.event.EventDataChannel
|
|||
import com.anytypeio.anytype.data.auth.event.EventRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.event.FileLimitsDataChannel
|
||||
import com.anytypeio.anytype.data.auth.event.FileLimitsRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.event.PushKeyRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.event.SubscriptionDataChannel
|
||||
import com.anytypeio.anytype.data.auth.event.SubscriptionEventRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.status.SyncAndP2PStatusEventsStore
|
||||
|
@ -128,12 +129,14 @@ object EventModule {
|
|||
logger: MiddlewareProtobufLogger,
|
||||
@Named(DEFAULT_APP_COROUTINE_SCOPE) scope: CoroutineScope,
|
||||
channel: EventHandlerChannel,
|
||||
syncP2PStore: SyncAndP2PStatusEventsStore
|
||||
syncP2PStore: SyncAndP2PStatusEventsStore,
|
||||
pushKeyRemoteChannel: PushKeyRemoteChannel
|
||||
): EventProxy = EventHandler(
|
||||
scope = scope,
|
||||
logger = logger,
|
||||
channel = channel,
|
||||
syncP2PStore = syncP2PStore
|
||||
syncP2PStore = syncP2PStore,
|
||||
pushKeyRemoteChannel = pushKeyRemoteChannel
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.anytypeio.anytype.di.feature.multiplayer.RequestJoinSpaceDependencies
|
|||
import com.anytypeio.anytype.di.feature.multiplayer.ShareSpaceDependencies
|
||||
import com.anytypeio.anytype.di.feature.multiplayer.SpaceJoinRequestDependencies
|
||||
import com.anytypeio.anytype.di.feature.notifications.NotificationDependencies
|
||||
import com.anytypeio.anytype.di.feature.notifications.PushContentDependencies
|
||||
import com.anytypeio.anytype.di.feature.objects.SelectObjectTypeDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingDependencies
|
||||
import com.anytypeio.anytype.di.feature.onboarding.OnboardingStartDependencies
|
||||
|
@ -143,7 +144,8 @@ interface MainComponent :
|
|||
DebugDependencies,
|
||||
CreateObjectTypeDependencies,
|
||||
SpaceTypesDependencies,
|
||||
SpacePropertiesDependencies
|
||||
SpacePropertiesDependencies,
|
||||
PushContentDependencies
|
||||
{
|
||||
|
||||
fun inject(app: AndroidApplication)
|
||||
|
@ -414,4 +416,9 @@ abstract class ComponentDependenciesModule {
|
|||
@IntoMap
|
||||
@ComponentDependenciesKey(SpacePropertiesDependencies::class)
|
||||
abstract fun provideSpacePropertiesDependencies(component: MainComponent): ComponentDependencies
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ComponentDependenciesKey(PushContentDependencies::class)
|
||||
abstract fun providePushContentDependencies(component: MainComponent): ComponentDependencies
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package com.anytypeio.anytype.di.main
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.device.DeviceTokenStoringServiceImpl
|
||||
import com.anytypeio.anytype.di.main.ConfigModule.DEFAULT_APP_COROUTINE_SCOPE
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
|
@ -11,12 +13,14 @@ import com.anytypeio.anytype.domain.config.ConfigStorage
|
|||
import com.anytypeio.anytype.domain.debugging.DebugAccountSelectTrace
|
||||
import com.anytypeio.anytype.domain.debugging.Logger
|
||||
import com.anytypeio.anytype.domain.device.NetworkConnectionStatus
|
||||
import com.anytypeio.anytype.domain.device.DeviceTokenStoringService
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.multiplayer.ActiveSpaceMemberSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.multiplayer.DefaultUserPermissionProvider
|
||||
import com.anytypeio.anytype.domain.multiplayer.SpaceViewSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
|
||||
import com.anytypeio.anytype.domain.notifications.RegisterDeviceToken
|
||||
import com.anytypeio.anytype.domain.objects.DefaultStoreOfObjectTypes
|
||||
import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
|
||||
|
@ -223,14 +227,16 @@ object SubscriptionsModule {
|
|||
permissions: UserPermissionProvider,
|
||||
isSpaceDeleted: SpaceDeletedStatusWatcher,
|
||||
profileSubscriptionManager: ProfileSubscriptionManager,
|
||||
networkConnectionStatus: NetworkConnectionStatus
|
||||
networkConnectionStatus: NetworkConnectionStatus,
|
||||
deviceTokenStoringService: DeviceTokenStoringService
|
||||
): GlobalSubscriptionManager = GlobalSubscriptionManager.Default(
|
||||
types = types,
|
||||
relations = relations,
|
||||
permissions = permissions,
|
||||
isSpaceDeleted = isSpaceDeleted,
|
||||
profile = profileSubscriptionManager,
|
||||
networkConnectionStatus = networkConnectionStatus
|
||||
networkConnectionStatus = networkConnectionStatus,
|
||||
deviceTokenStoringService = deviceTokenStoringService
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -259,4 +265,19 @@ object SubscriptionsModule {
|
|||
repo = repo,
|
||||
dispatchers = dispatchers
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun deviceTokenStoreService(
|
||||
@Named("encrypted") sharedPreferences: SharedPreferences,
|
||||
registerDeviceToken: RegisterDeviceToken,
|
||||
dispatchers: AppCoroutineDispatchers,
|
||||
@Named(DEFAULT_APP_COROUTINE_SCOPE) scope: CoroutineScope
|
||||
): DeviceTokenStoringService = DeviceTokenStoringServiceImpl(
|
||||
sharedPreferences = sharedPreferences,
|
||||
registerDeviceToken = registerDeviceToken,
|
||||
dispatchers = dispatchers,
|
||||
scope = scope
|
||||
)
|
||||
}
|
|
@ -710,4 +710,8 @@ sealed class Command {
|
|||
val blockId: Id,
|
||||
val properties: List<Key>
|
||||
) : Command()
|
||||
|
||||
data class RegisterDeviceToken(
|
||||
val token: String
|
||||
) : Command()
|
||||
}
|
|
@ -105,4 +105,8 @@ class AuthCacheDataStore(private val cache: AuthCache) : AuthDataStore {
|
|||
override suspend fun cancelAccountMigration(account: Id) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override suspend fun registerDeviceToken(request: Command.RegisterDeviceToken) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
|
@ -121,4 +121,8 @@ class AuthDataRepository(
|
|||
override suspend fun debugExportLogs(dir: String): String {
|
||||
return factory.remote.debugExportLogs(dir)
|
||||
}
|
||||
|
||||
override suspend fun registerDeviceToken(command: Command.RegisterDeviceToken) {
|
||||
factory.remote.registerDeviceToken(command)
|
||||
}
|
||||
}
|
|
@ -47,4 +47,6 @@ interface AuthDataStore {
|
|||
suspend fun getNetworkMode(): NetworkModeConfig
|
||||
suspend fun setNetworkMode(modeConfig: NetworkModeConfig)
|
||||
suspend fun debugExportLogs(dir: String): String
|
||||
|
||||
suspend fun registerDeviceToken(request: Command.RegisterDeviceToken)
|
||||
}
|
|
@ -28,4 +28,6 @@ interface AuthRemote {
|
|||
suspend fun getVersion(): String
|
||||
suspend fun setInitialParams(command: Command.SetInitialParams)
|
||||
suspend fun debugExportLogs(dir: String): String
|
||||
|
||||
suspend fun registerDeviceToken(command: Command.RegisterDeviceToken)
|
||||
}
|
|
@ -110,4 +110,8 @@ class AuthRemoteDataStore(
|
|||
override suspend fun debugExportLogs(dir: String): String {
|
||||
return authRemote.debugExportLogs(dir)
|
||||
}
|
||||
|
||||
override suspend fun registerDeviceToken(command: Command.RegisterDeviceToken) {
|
||||
authRemote.registerDeviceToken(command)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.anytypeio.anytype.device
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.fold
|
||||
import com.anytypeio.anytype.domain.device.DeviceTokenStoringService
|
||||
import com.anytypeio.anytype.domain.notifications.RegisterDeviceToken
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
class DeviceTokenStoringServiceImpl @Inject constructor(
|
||||
private val sharedPreferences: SharedPreferences,
|
||||
private val registerDeviceToken: RegisterDeviceToken,
|
||||
private val dispatchers: AppCoroutineDispatchers,
|
||||
private val scope: CoroutineScope
|
||||
) : DeviceTokenStoringService {
|
||||
|
||||
override fun saveToken(token: String) {
|
||||
scope.launch(dispatchers.io) {
|
||||
Timber.d("Saving token: $token")
|
||||
sharedPreferences.edit().apply {
|
||||
putString(PREF_KEY, token)
|
||||
apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun start() {
|
||||
val token = sharedPreferences.getString(PREF_KEY, null)
|
||||
if (!token.isNullOrEmpty()) {
|
||||
scope.launch(dispatchers.io) {
|
||||
val params = RegisterDeviceToken.Params(token = token)
|
||||
registerDeviceToken.async(params).fold(
|
||||
onSuccess = {
|
||||
Timber.d("Successfully registered token: $token")
|
||||
},
|
||||
onFailure = { error ->
|
||||
Timber.w("Failed to register token: $token, error: $error")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PREF_KEY = "prefs.device_token"
|
||||
}
|
||||
}
|
|
@ -64,4 +64,6 @@ interface AuthRepository {
|
|||
suspend fun getNetworkMode(): NetworkModeConfig
|
||||
suspend fun setNetworkMode(modeConfig: NetworkModeConfig)
|
||||
suspend fun debugExportLogs(dir: String): String
|
||||
|
||||
suspend fun registerDeviceToken(command: Command.RegisterDeviceToken)
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.anytypeio.anytype.domain.device
|
||||
|
||||
interface DeviceTokenStoringService {
|
||||
fun saveToken(token: String)
|
||||
fun start()
|
||||
fun stop()
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.anytypeio.anytype.domain.notifications
|
||||
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import javax.inject.Inject
|
||||
|
||||
class RegisterDeviceToken @Inject constructor(
|
||||
private val repository: AuthRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<RegisterDeviceToken.Params, Unit>(dispatchers.io) {
|
||||
|
||||
override suspend fun doWork(params: Params) {
|
||||
val command = Command.RegisterDeviceToken(
|
||||
token = params.token,
|
||||
)
|
||||
repository.registerDeviceToken(command = command)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val token: String
|
||||
)
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.domain.subscriptions
|
||||
|
||||
import com.anytypeio.anytype.domain.device.DeviceTokenStoringService
|
||||
import com.anytypeio.anytype.domain.device.NetworkConnectionStatus
|
||||
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
|
||||
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
|
||||
|
@ -19,7 +20,8 @@ interface GlobalSubscriptionManager {
|
|||
private val permissions: UserPermissionProvider,
|
||||
private val isSpaceDeleted: SpaceDeletedStatusWatcher,
|
||||
private val profile: ProfileSubscriptionManager,
|
||||
private val networkConnectionStatus: NetworkConnectionStatus
|
||||
private val networkConnectionStatus: NetworkConnectionStatus,
|
||||
private val deviceTokenStoringService: DeviceTokenStoringService
|
||||
) : GlobalSubscriptionManager {
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -29,6 +31,7 @@ interface GlobalSubscriptionManager {
|
|||
isSpaceDeleted.onStart()
|
||||
profile.onStart()
|
||||
networkConnectionStatus.start()
|
||||
deviceTokenStoringService.start()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
|
@ -38,6 +41,7 @@ interface GlobalSubscriptionManager {
|
|||
isSpaceDeleted.onStop()
|
||||
profile.onStop()
|
||||
networkConnectionStatus.stop()
|
||||
deviceTokenStoringService.stop()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ dataStoreVersion = '1.1.4'
|
|||
amplitudeVersion = '3.35.1'
|
||||
coilComposeVersion = '3.1.0'
|
||||
sentryVersion = '7.13.0'
|
||||
firebaseBomVersion = "33.13.0"
|
||||
|
||||
composeQrCodeVersion = '1.0.1'
|
||||
fragmentComposeVersion = "1.8.6"
|
||||
|
@ -153,12 +154,14 @@ navigationCompose = { module = "androidx.navigation:navigation-compose", version
|
|||
composeQrCode = { module = "com.lightspark:compose-qr-code", version.ref = "composeQrCodeVersion" }
|
||||
playBilling = { module = "com.android.billingclient:billing", version = "7.1.1" }
|
||||
fragmentCompose = { group = "androidx.fragment", name = "fragment-compose", version.ref = "fragmentComposeVersion" }
|
||||
firebaseBom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBomVersion" }
|
||||
firebaseMessaging = { module = "com.google.firebase:firebase-messaging"}
|
||||
|
||||
[bundles]
|
||||
|
||||
[plugins]
|
||||
application = { id = "com.android.application", version = "8.8.2" }
|
||||
library = { id = "com.android.library", version = "8.8.2" }
|
||||
application = { id = "com.android.application", version = "8.9.1" }
|
||||
library = { id = "com.android.library", version = "8.9.1" }
|
||||
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlinVersion" }
|
||||
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlinVersion" }
|
||||
dokka = { id = "org.jetbrains.dokka", version.ref = "dokkaVersion" }
|
||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
@ -96,4 +96,8 @@ class AuthMiddleware(
|
|||
override suspend fun debugExportLogs(dir: String): String {
|
||||
return middleware.debugExportLogs(dir)
|
||||
}
|
||||
|
||||
override suspend fun registerDeviceToken(command: Command.RegisterDeviceToken) {
|
||||
middleware.registerDeviceToken(command = command)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import anytype.Event
|
||||
import com.anytypeio.anytype.data.auth.event.PushKeyRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.status.SyncAndP2PStatusEventsStore
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import java.io.IOException
|
||||
|
@ -17,10 +18,14 @@ class EventHandler @Inject constructor(
|
|||
private val logger: MiddlewareProtobufLogger,
|
||||
private val scope: CoroutineScope,
|
||||
private val channel: EventHandlerChannel,
|
||||
private val syncP2PStore: SyncAndP2PStatusEventsStore
|
||||
private val syncP2PStore: SyncAndP2PStatusEventsStore,
|
||||
private val pushKeyRemoteChannel: PushKeyRemoteChannel
|
||||
) : EventProxy {
|
||||
|
||||
init {
|
||||
scope.launch {
|
||||
pushKeyRemoteChannel.start()
|
||||
}
|
||||
scope.launch {
|
||||
syncP2PStore.start()
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.middleware.interactor
|
|||
|
||||
import anytype.Rpc
|
||||
import anytype.Rpc.Chat.ReadMessages.ReadType
|
||||
import anytype.Rpc.PushNotification.RegisterToken.Platform
|
||||
import anytype.model.Block
|
||||
import anytype.model.ParticipantPermissionChange
|
||||
import anytype.model.Range
|
||||
|
@ -2978,6 +2979,17 @@ class Middleware @Inject constructor(
|
|||
return response.event.toPayload()
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun registerDeviceToken(command: Command.RegisterDeviceToken) {
|
||||
val request = Rpc.PushNotification.RegisterToken.Request(
|
||||
token = command.token,
|
||||
platform = Platform.Android
|
||||
)
|
||||
logRequestIfDebug(request)
|
||||
val (response, time) = measureTimedValue { service.pushNotificationRegisterToken(request) }
|
||||
logResponseIfDebug(response, time)
|
||||
}
|
||||
|
||||
private fun logRequestIfDebug(request: Any) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
logger.logRequest(request).also {
|
||||
|
|
|
@ -634,4 +634,7 @@ interface MiddlewareService {
|
|||
|
||||
@Throws(Exception::class)
|
||||
fun blockDataViewRelationSet(request: Rpc.BlockDataview.Relation.Set.Request): Rpc.BlockDataview.Relation.Set.Response
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun pushNotificationRegisterToken(request: Rpc.PushNotification.RegisterToken.Request): Rpc.PushNotification.RegisterToken.Response
|
||||
}
|
|
@ -2573,4 +2573,17 @@ class MiddlewareServiceImplementation @Inject constructor(
|
|||
return response
|
||||
}
|
||||
}
|
||||
|
||||
override fun pushNotificationRegisterToken(request: Rpc.PushNotification.RegisterToken.Request): Rpc.PushNotification.RegisterToken.Response {
|
||||
val encoded = Service.pushNotificationRegisterToken(
|
||||
Rpc.PushNotification.RegisterToken.Request.ADAPTER.encode(request)
|
||||
)
|
||||
val response = Rpc.PushNotification.RegisterToken.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != Rpc.PushNotification.RegisterToken.Response.Error.Code.NULL) {
|
||||
throw Exception(error.description)
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue