React Native Firebase Notifications aren't always shown - firebase

We have a React-Native app on iOS and Android. We use RN 0.61.5 and react-native-firebase 5.5.6.
We use react-native-firebase/notifications to add local notifications on the device. When we test this these notifications are planned correct but we get the feedback from some of our users that they don’t receive the notifications. I have added our notifications.ts file and our NotificationListener.tsx file below.
Does someone have an idea, possible reason of tips for debug/improve/fix our notifications?
Code
notifications.ts:
// Firebase Notifications
// ---
// Custom implementation on top of the Firebase Notifications library.
// This class is responsable for creating, scheduling and re-scheduling notifications.
// ------------------------------------------------------------------------- /
import firebase from "react-native-firebase";
import { Notification } from "react-native-firebase/notifications";
import { Recycle } from "#shd-types/fp-recycle-api";
import { isEmpty } from "ramda";
import { Store } from "../../store";
import { IS_ANDROID, IS_IOS } from "../../utils/device-info";
import i18n, { manualTranslate } from "../../utils/i18n";
import { NotificationsState } from "../../features/notifications/store/notifications.types";
import { CollectionRoundsState } from "../../features/collection-rounds/store/collectionRounds.types";
import { ProfileState } from "../../features/profile/store/profile.types";
const MAX_ALLOWED_NOTIFICATIONS = 64;
class FirebaseNotifications {
private permissionsGranted: boolean = false;
private language: string;
private notificationState: NotificationsState;
private collectionRoundsState: CollectionRoundsState;
private profileState: ProfileState;
constructor() {
// Ask for permission to send notifications
this.init();
const store: any = Store.getState();
this.language = store.global.language;
this.notificationState = store.notifications;
this.collectionRoundsState = store.collectionRounds;
this.profileState = store.profile;
// Create an Android Notification Channel
// More info on this here: https://rnfirebase.io/docs/v5.x.x/notifications/android-channels
this.initChannels();
}
async init(): Promise<void> {
const store: any = Store.getState();
this.language = store.global.language;
this.notificationState = store.notifications;
this.collectionRoundsState = store.collectionRounds;
this.profileState = store.profile;
if (this.permissionsGranted) {
return Promise.resolve();
}
const enabled = await firebase.messaging().hasPermission();
if (!enabled) {
try {
await firebase.messaging().requestPermission();
this.permissionsGranted = true;
} catch (error) {
// User has rejected permissions
this.permissionsGranted = false;
return Promise.reject();
}
} else {
this.permissionsGranted = true;
}
return Promise.resolve();
}
async initChannels() {
// Create the channel groups
await firebase.notifications().android.createChannelGroups([
// Main channel group
new firebase.notifications.Android.ChannelGroup("general", "General"),
// Channel group for each address
new firebase.notifications.Android.ChannelGroup("collections-home", "Home"),
]);
// Build a channel
const channel = new firebase.notifications.Android.Channel("collection-rounds-channel", "Collection Rounds", firebase.notifications.Android.Importance.Max)
.setDescription("Notifications for Collection Rounds")
.setGroup("collections-home");
// Create the channel
firebase.notifications().android.createChannel(channel);
}
// Collection Build Methods
// ------------------------------------------------------------------------- /
setAndroidNotificationProps(notification: Notification, channelId?: string, group?: string) {
// https://rnfirebase.io/docs/v5.x.x/notifications/reference/AndroidNotification
notification
.android.setLocalOnly(true)
.android.setPriority(firebase.notifications.Android.Priority.Max)
// Notification Style
.android.setColor("green") // Sets the accent color to use
.android.setVibrate([500, 500]) // Set notification vibration pattern.
.android.setLights(0xFF97E92A, 500, 500) // Set notification light to green.
.android.setSmallIcon("ic_launcher");
if (channelId) {
notification
.android.setChannelId(channelId);
}
if (group) {
notification
.android.setGroup(group)
.android.setGroupAlertBehaviour(firebase.notifications.Android.GroupAlert.All);
}
}
setIOSNotificationProps(notification: Notification, category?: string) {
// https://rnfirebase.io/docs/v5.x.x/notifications/reference/AndroidNotification
notification
.ios.setHasAction(false); // IOS 9 only.
if (category) {
notification
.ios.setCategory(category);
}
}
buildOpenAppNotification(fireDate: number): Notification {
const notification = new firebase.notifications.Notification()
.setNotificationId(`general-open-app-reminder-${fireDate}`)
.setTitle(i18n._("notifications.appRefresh.title"))
.setBody(i18n._("notifications.appRefresh.body"))
.setSound("default")
.setData({
schedule: {
fireDate,
},
});
if (IS_ANDROID) {
this.setAndroidNotificationProps(notification, "general");
}
if (IS_IOS) {
this.setIOSNotificationProps(notification, "general");
notification
.ios.setBadge(1);
}
return notification;
}
buildCollectionNotification(collection: Recycle.Collection.CollectionRound, fireDate?: number, sameDay = false): Notification {
const collectionTypeNames = collection.types.map((collectionType: Recycle.Type.Item) => manualTranslate(collectionType.name, this.language));
const notificationTitle = sameDay
? `${i18n._("notifications.collectionSameDay.title")}: ${collectionTypeNames.join(", ")}`
: `${i18n._("notifications.collectionDayBefore.title")}: ${collectionTypeNames.join(", ")}`;
// TODO: Map this to the location, if multiple
const notificationSubtitle = i18n._(this.profileState.address[0].alias);
const notificationBody = sameDay
? i18n._("notifications.collectionSameDay.body")
: i18n._("notifications.collectionDayBefore.body");
const notificationBodyExtended = sameDay
? i18n._("notifications.collectionSameDay.bodyExtended")
: i18n._("notifications.collectionDayBefore.bodyExtended");
const notification = new firebase.notifications.Notification()
.setNotificationId(`notification-collection-${collection.id}-${fireDate}`)
.setTitle(notificationTitle)
.setSubtitle(notificationSubtitle)
.setBody(notificationBody)
.setData({
...collection,
schedule: {
fireDate,
},
})
.setSound("default");
if (IS_ANDROID) {
this.setAndroidNotificationProps(notification, "collection-rounds-channel", "collections");
notification.android
.setBigText(
notificationBodyExtended,
notificationTitle,
notificationBody
);
}
if (IS_IOS) {
this.setIOSNotificationProps(notification, "collections");
}
return notification;
}
resetNotificationBadge() {
if (IS_IOS) {
const notifications = firebase.notifications();
notifications.setBadge(0);
}
}
// Scheduling Methods
// ------------------------------------------------------------------------- /
async rescheduleNotifications(collections?: Recycle.Collection.CollectionRound[]) {
// Clear all scheduled notifications
const notifications = await firebase.notifications().getScheduledNotifications();
if (notifications) {
notifications
.forEach((notification: Notification) => {
firebase.notifications().cancelNotification(notification.notificationId);
});
}
collections = collections ? collections : this.collectionRoundsState.data;
if (!collections) {
return;
}
// Check if the user has given permission to receive notifications
try {
await this.init();
} catch (err) {
return;
}
// Fetch the notificationsSettings
const homeNotificationSettings = this.notificationState.settings.home;
// TODO
// 1. Account for the amount of notifications (e.g. the day before AND the current day)
// 2. Account for the amount of addresses to schedule for.
//
// We will simulate this for now. (simplified)
const numberOfNotificationsPerCollection = Object.values(homeNotificationSettings.time).filter((timeSetting) => timeSetting.enabled).length;
const numberOfAddresses = 1;
const numberOfCollectionsToSchedule = Math.floor(MAX_ALLOWED_NOTIFICATIONS / (numberOfAddresses * numberOfNotificationsPerCollection)) - 1;
// TODO
// 1. Account for the time when we want the notification.
let lastNotificationTime = 0;
let collectionTypesToNotNotify: string[] = [];
// Filter out the collectionTypes we don't want a notification for.
if (homeNotificationSettings) {
collectionTypesToNotNotify = Object.values(homeNotificationSettings.categories)
.filter((category) => !category.enabled )
.map((category) => category.key);
}
// Reschedule all collections
collections
.filter((collection) => {
// Filter out collections that have passed
if (new Date(collection.date).valueOf() < new Date().valueOf()) {
return false;
}
// Filter out collections that are not wanted
if (collectionTypesToNotNotify.length) {
const allow = [];
const localCollectionTypes = collection.types.map((type) => type.id);
for (const collectionType of localCollectionTypes) {
allow.push(!collectionTypesToNotNotify.includes(collectionType));
}
// The collection has at least 1 item we want notifications for.
return allow.includes(true);
}
return true;
})
.map((collection) => {
// Filter out the collections the user does not want.
if (!collectionTypesToNotNotify.length) {
return collection;
}
const localCollectionTypes = collection.types.map((type) => type.id);
return {
...collection,
types: localCollectionTypes.filter((collectionType) => {
return !collectionTypesToNotNotify.includes(collectionType);
}),
};
})
.slice(0, numberOfCollectionsToSchedule)
.forEach((collection, index, arr) => {
const collectionDay = new Date(collection.date);
let collectionNotificationTime = 0;
let collectionHour = 0;
let collectionMinutes = 0;
if (homeNotificationSettings.time.dayBefore.enabled) {
// Get the day before
const collectionNotificationDate = new Date(collectionDay).setDate(collectionDay.getDate() - 1);
// Set the notification hour
collectionHour = homeNotificationSettings.time.dayBefore.hours;
collectionMinutes = homeNotificationSettings.time.dayBefore.minutes;
collectionNotificationTime = new Date(collectionNotificationDate).setHours(collectionHour, collectionMinutes);
// Schedule the notification if it triggers in the future
this.scheduleCollectionNotification(collection, collectionNotificationTime);
}
if (homeNotificationSettings.time.dayOf.enabled) {
// Set the notification hour
collectionHour = homeNotificationSettings.time.dayOf.hours;
collectionMinutes = homeNotificationSettings.time.dayOf.minutes;
collectionNotificationTime = new Date(collectionDay).setHours(collectionHour, collectionMinutes);
// Schedule the notification if it triggers in the future
this.scheduleCollectionNotification(collection, collectionNotificationTime, true);
}
// Schedule the "open your app please" notification after 10 notifcations
// And after the last one
if ((index !== 0 && index % 10 === 0) || (index === arr.length - 1)) {
// Plan the reminder 1 day after the previous notification
const collectionDate = new Date(collectionDay).setDate(collectionDay.getDate() + 1);
lastNotificationTime = new Date(collectionDate).setHours(collectionHour, collectionMinutes);
firebase.notifications().scheduleNotification(
this.buildOpenAppNotification(lastNotificationTime),
{ fireDate: lastNotificationTime }
);
}
});
}
scheduleCollectionNotification(collection: Recycle.Collection.CollectionRound, fireDate: number, sameDay = false) {
// Schedule the notification if it triggers in the future
if (fireDate > new Date().valueOf() && !isEmpty(this.notificationState.settings.home.categories)) {
firebase.notifications().scheduleNotification(
this.buildCollectionNotification(collection, fireDate, sameDay),
{ fireDate }
);
}
}
}
export default new FirebaseNotifications();
NotificationListener.tsx:
import React from "react";
import firebase from "react-native-firebase";
import { Notification, NotificationOpen } from "react-native-firebase/notifications";
interface Props {
children: any;
}
class NotificationListener extends React.Component<Props> {
private notificationDisplayedListener: (notification?: Notification) => void;
private notificationListener: (notification?: Notification) => void;
private notificationOpenedListener: (notificationOpen?: NotificationOpen) => void;
constructor(props: Props) {
super(props);
this.notificationDisplayedListener = firebase.notifications().onNotificationDisplayed(this.onNotificationDisplayed);
this.notificationListener = firebase.notifications().onNotification(this.onNotification);
this.notificationOpenedListener = firebase.notifications().onNotificationOpened(this.onNotificationOpened);
this.onNotificationDisplayed = this.onNotificationDisplayed.bind(this);
this.onNotification = this.onNotification.bind(this);
this.onNotificationOpened = this.onNotificationOpened.bind(this);
}
// Lifecycle Methods
// ------------------------------------------------------------------------- /
// https://rnfirebase.io/docs/v5.x.x/notifications/receiving-notifications#App-Closed
async componentDidMount() {
const notificationOpen: NotificationOpen = await firebase.notifications().getInitialNotification();
if (notificationOpen) {
// App was opened by a notification
this.onNotificationOpened(notificationOpen);
}
}
componentWillUnmount() {
this.notificationDisplayedListener();
this.notificationListener();
this.notificationOpenedListener();
}
// Callback Methods
// ------------------------------------------------------------------------- /
// Triggered when a particular notification has been displayed
onNotificationDisplayed(notification: Notification) {
// ANDROID: Remote notifications do not contain the channel ID. You will have to specify this manually if you'd like to re-display the notification.
// Leave this for debugging purposes
// console.log("Notification Displayed!:", notification);
}
// Triggered when a particular notification has been received, but not displayed
onNotification(notification: Notification) {
// Leave this for debugging purposes
// console.log("Notification received, but not displayed!:", notification);
// Force the notification in the OS NotificationBar
firebase.notifications().displayNotification(notification);
}
// Triggered when a particular notification has been clicked / tapped / opened whent he app is in the foreground or background.
onNotificationOpened(notificationOpen: NotificationOpen) {
// Get the action triggered by the notification being opened
const action = notificationOpen.action;
// Get information about the notification that was opened
const notification: Notification = notificationOpen.notification;
// Leave this for debugging purposes
// console.log("Notification Opened!:", notificationOpen);
// Remove the notification once it has been openend.
firebase.notifications().removeDeliveredNotification(notificationOpen.notification.notificationId);
}
// Render Methods
// ------------------------------------------------------------------------- /
render() {
return this.props.children;
}
}
export default NotificationListener;```

Related

404 page in nextjs app dir constantly refreshes with middleware

within my project, we use the nextjs app directory
however with that, it does not include root 404 pages, so we instead use the pages/404.tsx file. in our middleware, it uses next-auth and vercel edge config to send the user to a maintenance page (if enabled on edge config) and to check for auth pages and such, but even with everything commented out, it makes the 404 page constantly refresh itself
middleware.ts:
import { getToken } from "next-auth/jwt";
import { withAuth } from "next-auth/middleware";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { get } from "#vercel/edge-config";
export const config = {
matcher: ["/((?!_next|icon.svg|favicon.ico|api).*)"]
};
export default withAuth(
async function middleware(req: NextRequest) {
// if (process.env.EDGE_CONFIG && process.env.NODE_ENV !== "development") {
// if (req.nextUrl.pathname.startsWith("/maintenance")) return null;
// const isInMaintenanceMode = await get("isInMaintenanceMode");
// console.log("isInMaintenanceMode", isInMaintenanceMode);
// if (isInMaintenanceMode) {
// return NextResponse.redirect(new URL("/maintenance", req.url));
// }
// }
// if (req.nextUrl.pathname.startsWith("/dashboard") || req.nextUrl.pathname.startsWith("/login") || req.nextUrl.pathname.startsWith("/register")) {
// console.log("matches")
// const token = await getToken({ req });
// const isAuth = !!token;
// const isAuthPage = req.nextUrl.pathname.startsWith("/login") || req.nextUrl.pathname.startsWith("/register");
// if (isAuthPage) {
// if (isAuth) {
// return NextResponse.redirect(new URL("/dashboard", req.url));
// }
// return null;
// }
// if (!isAuth) {
// let from = req.nextUrl.pathname;
// if (req.nextUrl.search) {
// from += req.nextUrl.search;
// }
// return NextResponse.redirect(new URL(`/login?callbackUrl=${encodeURIComponent(from)}`, req.url));
// }
// }
},
{
callbacks: {
async authorized() {
return true;
}
}
}
);
i have tried to comment out the middleware (which had no effect on the error)
and i have also made the matcher only target one page, which worked, however i need it to target all pages so that the middleware function works

I want lockscreen on react native application and check passwords before screen load

I stored the app passwords in local storage of app and I just want to check the passwords before the screen renders in App.js
var passwords = null;
function get_passwords() {
// fetch the user defined settings
var db = openDatabase({ name: 'trans_DB.db', createFromLocation: '~www/test_Db.db' });
//to read currency
db.transaction((tx) => {
tx.executeSql(
'SELECT * FROM password_table', [],
(tx, results) => {
var len = results.rows.length;
if (len > 0) {
passwords = results.rows.item(0).passwords
}
}
);
});
}
function App(){
get_passwords();
if(passwords == null){
return lockScreen(); //contains lockscreen
}
else{
return mainScreen(); //if user didn't set the security to app then render main screen
}
}
I tried this but issue is database returns the values late and screen loads first before getting values from databases
you can set the password in state after retrieving from database
import React, { useState, useEffect } from 'react';
function App(){
const [passwords, setPasswords] = useState("");
// set password
useEffect(() => {
get_passwords()
},[]);
const get_passwords = () => {
// fetch the user defined settings
var db = openDatabase({
name: "trans_DB.db",
createFromLocation: "~www/test_Db.db",
});
//to read currency
db.transaction(tx => {
tx.executeSql("SELECT * FROM password_table", [], (tx, results) => {
var len = results.rows.length;
if (len > 0) {
passwords = results.rows.item(0).passwords;
setPasswords(passwords)
}
});
});
};
if(passwords == ""){
return lockScreen(); //contains lockscreen
}
else{
return mainScreen(); //if user didn't set the security to app then render main screen
}
}

React Native: Firebase notification not showing

When trying to send test notification from Firebase my app does not receive any event. In the notification composer I am picking specifically the fcmToken of my iOS device:
I have checked that I am using the right fcmToken and authentication keys.
Could it have something to do with the version of react-native-firebase that I am using? Or that the initialization routine is in the react-navigator?
react-native-firebase#5.5.6
react-navigation#3.11.1
Navigator.js
export default class Navigator extends Component {
constructor(props) {
super(props)
}
async componentDidMount() {
FirebaseService.checkPermission();
FirebaseService.createNotificationListeners();
}
//Remove listeners allocated in createNotificationListeners()
componentWillUnmount() {
FirebaseService.notificationListener();
FirebaseService.notificationOpenedListener();
}
render() {
return (
<View style={{ flex: 1 }}>
<Route
onNavigationStateChange={(prevState, currentState) => {
const currentScreen = getActiveRouteName(currentState);
const prevScreen = getActiveRouteName(prevState);
nav.activeRouteName = currentScreen;
if (prevScreen !== currentScreen) {
if (currentScreen == "captureView") {
this.resetSafearea("never")
} else {
this.resetSafearea("always")
}
}
}}
/>
</View>
);
}
}
FirebaseService.js
import AsyncStorage from '#react-native-community/async-storage';
import Firebase from "react-native-firebase";
export default class FirebaseService {
//1
static checkPermission = async () => {
const enabled = await Firebase.messaging().hasPermission();
if (enabled) {
FirebaseService.getToken();
} else {
FirebaseService.requestPermission();
}
}
//2
static requestPermission = async () => {
try {
await Firebase.messaging().requestPermission();
// User has authorised
FirebaseService.getToken();
} catch (error) {
// User has rejected permissions
console.log('permission rejected');
}
}
//3
static getToken = async () => {
let fcmToken = await AsyncStorage.getItem('fcmToken');
if (!fcmToken) {
fcmToken = await Firebase.messaging().getToken();
if (fcmToken) {
// user has a device token
await AsyncStorage.setItem('fcmToken', fcmToken);
}
}
return fcmToken;
}
static createNotificationListeners = async () => {
/*
* Triggered when a particular notification has been received in foreground
* */
FirebaseService.notificationListener = Firebase.notifications().onNotification((notification) => {
const { title, body } = notification;
console.log("notification", notification);
});
/*
* If your app is in background, you can listen for when a notification is clicked / tapped / opened as follows:
* */
FirebaseService.notificationOpenedListener = Firebase.notifications().onNotificationOpened((notificationOpen) => {
const { title, body } = notificationOpen.notification;
console.log("notification", notification);
});
/*
* If your app is closed, you can check if it was opened by a notification being clicked / tapped / opened as follows:
* */
const notificationOpen = await Firebase.notifications().getInitialNotification();
if (notificationOpen) {
const { title, body } = notificationOpen.notification;
console.log("notification", notification);
}
/*
* Triggered for data only payload in foreground
* */
FirebaseService.messageListener = Firebase.messaging().onMessage((message) => {
//process data message
console.log("message", JSON.stringify(message));
});
console.log("Notification listeners created.");
}
}
The reason was that the push notification certificate was not installed on my system (there was no error showing it).
You will need one for development and one for production https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns

Sending data to an imported module in React Native

I have a module called Chat.js that imports Fire.js in order to send data (message comes into Chat.js, and Fire.js handles storage).
I have a recipient's user ID that is only currently available in Chat.js, but it is important to get to Fire.js in order to store appropriately.
I removed some info for brevity, this is my current Chat.js:
import Fire from './Fire';
class Chat extends React.Component<Props> {
state = {
messages: [],
};
get user() {
return {
name: this.props.navigation.state.params.name,
_id: Fire.shared.uid,
};
}
render() {
return (
<GiftedChat
messages={this.state.messages}
onSend={Fire.shared.send}
user={this.user}
/>
);
}
componentDidMount() {
Fire.shared.on(message =>
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, message),
}))
);
}
componentWillUnmount() {
Fire.shared.off();
}
}
export default Chat;
And this is my current Fire.js:
import firebase from 'react-native-firebase';
class Fire {
constructor() {
}
get ref() {
var recipient = 'recipientId'
return firebase.database().ref('messages/' + this.uid + '/' + recipient);
}
parse = snapshot => {
const { timestamp: numberStamp, text, user } = snapshot.val();
const { key: _id } = snapshot;
const timestamp = new Date(numberStamp);
const message = {
_id,
timestamp,
text,
user,
};
return message;
};
on = callback =>
this.ref
.limitToLast(20)
.on('child_added', snapshot => callback(this.parse(snapshot)));
// send the message to the Backend
send = messages => {
for (let i = 0; i < messages.length; i++) {
const { text, user } = messages[i];
const message = {
text,
user,
timestamp: this.timestamp,
};
this.append(message);
}
};
append = message => this.ref.push(message);
// close the connection to the Backend
off() {
this.ref.off();
}
}
Fire.shared = new Fire();
export default Fire;
I currently need to get the recipient ID, which is available in chat.js under
this.props.navigation.state.params.uid
Into the Fire.js lines:
get ref()
{
var recipient = 'recipientId'
I can't seem to get this uid into get ref()
Use getter and setters in Fire.js.
In Fire.js
setRecipient (id){
this.recipientId = id;
}
get getRecipientId () {
return this.recipientId;
}
And then call Fire.setRecipient(yourId) in Chat.js.

Network Check and show Toast on Http Request

I am very new to ionic, currently working/learning with Ionic 2. I would like to show a toast when a user goes offline. I am currently able to do that as shown in my code below (toast shows whenever user goes offline). However what i would like to do is show the toast on http request (pull to refresh and infinite scroll). So that even when data is already loaded, the toast gets displayed when the user tries to pull to refresh on load more data through infinite scroll then they get notified that they are offline.
export class HomePage {
datas:any = [];
page:number =1;
connected: Subscription;
disconnected: Subscription;
constructor(private toast: ToastController, private network: Network, public navCtrl: NavController, private wpapi: Wpapi) {
this.getPosts();
}
displayNetworkUpdate(connectionState: string){
//let networkType = this.network.type
this.toast.create({
message: `You are currently ${connectionState}, please re connect your data`,
duration: 3000
}).present();
}
ionViewDidEnter() {
this.disconnected = this.network.onDisconnect().subscribe(data => {
console.log(data)
this.displayNetworkUpdate(data.type);
}, error => console.error(error));
}
getPosts() {
//this.page = '1';
//this.wpapi.index(this.page)
this.wpapi.index(1)
.subscribe(data => {
this.datas = data;
console.log(this.datas);
});
}
loadMore(infiniteScroll) {
this.page++;
this.wpapi.index( this.page ).subscribe( datas => {
// Loads posts from WordPress API
let length = datas["length"];
if( length === 0 ) {
infiniteScroll.complete();
return;
}
for (var i = length - 1; i >= 0; i--) {
this.datas.push( datas[i] );
}
infiniteScroll.complete();
});
}
doRefresh(refresher) {
this.wpapi.index(1)
.subscribe(data => {
this.datas = data;
refresher.complete();
});
}
ionViewWillLeave(){
this.connected.unsubscribe();
this.disconnected.unsubscribe();
}
}
This is what i'm doing. In my app.components i have the connection subscriber, beeing it offline or online, so if a user goes offline i save a conn boolean variable with false, if online i save true in my localStorage and present a toast saying it has gone offline (if gone online there's no need to present a toast).
network.onDisconnect().subscribe(() => {
storage.set('conn', false);
let conoff = ToastCtrl.create({
closeButtonText: 'Ok',
showCloseButton: true,
message: 'You're not connected to internet.',
position: 'top'
});
conoff.present();
});
You can create a service to do this, something like
import { Injectable } from '#angular/core';
import { Storage } from '#ionic/storage';
import { ToastController, Platform } from 'ionic-angular';
#Injectable()
export class Verificador {
constructor(public toast: ToastController, public storage: Storage, public platform: Platform) {
}
verifyConnection = (): Promise<boolean> => {
return new Promise<boolean>((res, rej) => {
this.storage.get('conn').then(conn => {
if (conn) {
res(true);
} else {
let t = this.toast.create({
closeButtonText: 'Ok',
showCloseButton: true,
message: 'You can't do this without internet.',
position: 'top'
});
t.present();
res(false);
}
})
})
}
}
So in every component, page entering, http call, you import that service/provider and call the verifyConnection function, if it returns true you just let the user do what it needs to do, if it's false the provider will show the toast.
import { ConnVerification} from '../../../providers/ConnVerification';
#IonicPage()
#Component({
selector: 'your-page',
templateUrl: 'your-page',
providers: [ConnVerification]
})
export class YourPage {
constructor(public verif: ConnVerification){}
myFunctionForSomething(){
this.verif.verifyConnection().then(conn =>{
if(conn){
// DO YOUR CODE
}
// NO NEED FOR ELSE SINCE IT'S HANDLED ON PROVIDER
})
}
}
Hope it helps :)

Resources