diff --git a/src/addons/messages/messages.module.ts b/src/addons/messages/messages.module.ts index c6579af46..9f7748ff0 100644 --- a/src/addons/messages/messages.module.ts +++ b/src/addons/messages/messages.module.ts @@ -87,7 +87,7 @@ const preferencesRoutes: Routes = [ CoreUserDelegate.registerHandler(AddonMessagesSendMessageUserHandler.instance); // Sync some discussions when device goes online. - CoreNetwork.onConnect().subscribe(() => { + CoreNetwork.onConnectShouldBeStable().subscribe(() => { // Execute the callback in the Angular zone, so change detection doesn't stop working. NgZone.run(() => { AddonMessagesSync.syncAllDiscussions(undefined, true); diff --git a/src/core/initializers/watch-network.ts b/src/core/initializers/watch-network.ts index 9d8aabf5f..74c6a0261 100644 --- a/src/core/initializers/watch-network.ts +++ b/src/core/initializers/watch-network.ts @@ -16,9 +16,12 @@ import { CoreCronDelegate } from '@services/cron'; import { NgZone } from '@singletons'; import { CoreNetwork } from '@services/network'; +/** + * Initializer function. + */ export default function(): void { // When the app is re-connected, start network handlers that were stopped. - CoreNetwork.onConnect().subscribe(() => { + CoreNetwork.onConnectShouldBeStable().subscribe(() => { // Execute the callback in the Angular zone, so change detection doesn't stop working. NgZone.run(() => CoreCronDelegate.startNetworkHandlers()); }); diff --git a/src/core/services/filepool.ts b/src/core/services/filepool.ts index 1751636f0..3c633823a 100644 --- a/src/core/services/filepool.ts +++ b/src/core/services/filepool.ts @@ -150,7 +150,7 @@ export class CoreFilepoolProvider { this.checkQueueProcessing(); // Start queue when device goes online. - CoreNetwork.onConnect().subscribe(() => { + CoreNetwork.onConnectShouldBeStable().subscribe(() => { // Execute the callback in the Angular zone, so change detection doesn't stop working. NgZone.run(() => this.checkQueueProcessing()); }); diff --git a/src/core/services/network.ts b/src/core/services/network.ts index aeb49a4ae..b50a87601 100644 --- a/src/core/services/network.ts +++ b/src/core/services/network.ts @@ -38,9 +38,11 @@ export class CoreNetworkService extends Network { type!: string; protected connectObservable = new Subject<'connected'>(); + protected connectStableObservable = new Subject<'connected'>(); protected disconnectObservable = new Subject<'disconnected'>(); protected forceConnectionMode?: CoreNetworkConnection; protected online = false; + protected connectStableTimeout?: number; get connectionType(): CoreNetworkConnection { if (this.forceConnectionMode !== undefined) { @@ -146,6 +148,7 @@ export class CoreNetworkService extends Network { /** * Returns an observable to notify when the app is connected. * It will also be fired when connection type changes. + * If you're going to perform network requests once the device is connected, please use onConnectShouldBeStable instead. * * @returns Observable. */ @@ -153,6 +156,18 @@ export class CoreNetworkService extends Network { return this.connectObservable; } + /** + * Returns an observable to notify when the app is connected and it should already be a stable a connection. + * E.g. when leaving flight mode the device could connect to mobile network first and then to WiFi. + * If you're going to perform network requests once the device is connected, it's recommended to use this function instead of + * onConnect because some OS (e.g. Android) duplicate a request if the type of connection changes while the request is done. + * + * @returns Observable. + */ + onConnectShouldBeStable(): Observable<'connected'> { + return this.connectStableObservable; + } + /** * Returns an observable to notify when the app is disconnected. * @@ -166,10 +181,14 @@ export class CoreNetworkService extends Network { * Fires the correct observable depending on the connection status. */ protected fireObservable(): void { + clearTimeout(this.connectStableTimeout); this.checkOnline(); if (this.online) { this.connectObservable.next('connected'); + this.connectStableTimeout = window.setTimeout(() => { + this.connectStableObservable.next('connected'); + }, 5000); } else { this.disconnectObservable.next('disconnected'); } diff --git a/src/core/services/utils/iframe.ts b/src/core/services/utils/iframe.ts index 3314fc8dc..a35d72194 100644 --- a/src/core/services/utils/iframe.ts +++ b/src/core/services/utils/iframe.ts @@ -76,7 +76,7 @@ export class CoreIframeUtilsProvider { this.addOfflineWarning(element, src, isSubframe); // If the network changes, check it again. - const subscription = CoreNetwork.onConnect().subscribe(() => { + const subscription = CoreNetwork.onConnectShouldBeStable().subscribe(() => { // Execute the callback in the Angular zone, so change detection doesn't stop working. NgZone.run(() => { if (!this.checkOnlineFrameInOffline(element, isSubframe)) {