how to use "export interface CalendarNotificationTrigger"

In the docs here https://docs.expo.io/versions/v38.0.0/sdk/notifications/#calendarnotificationtrigger

I see:

export interface CalendarNotificationTrigger {  ... }

I didn’t see anywhere on this page on how to use this interface. To be honest, I’ve never seen

export interface

and I am not sure how to integrate or call it in my code.

Please let me know where I can find a full example of this integration.

My goal is to use this as a trigger in the scheduleNotificationAsync method as seen here:
https://docs.expo.io/versions/v38.0.0/sdk/notifications/

Thank you,

Hey @dj-designs,

What you’re looking at is to be used with TypeScript. Interfaces are used for typing which is why the section of the docs you linked to is titled “Types”. If you’re not using TS, you’ll not need to use this.

Cheers,
Adam

thanks for the quick reply @adamjnav

I was wondering if you could help me? I’ve been struggling with notifications for about three months now.

I really appreciate expo and I really just appreciate all the hard work from the expo team and how it makes it so easy to publish to the App Store. I really love it! I have been able to publish my first mobile app Using expo and this is been one of my goals for the past seven years.

I’ve looked at other mobile application solutions but I think expo is the most robust and makes it easiest to publish to the App Store.

At any rate I know you were very busy but I was wondering if you could help me to figure out how to do a simple local notification based on the date.

I’ve been looking at the API here: https://docs.expo.io/versions/v38.0.0/sdk/notifications/#schedulenotificationasyncnotificationrequest-notificationrequestinput-promisestring

and I can get the notification appear when I click button (based on the sample code on this page). but I can’t figure out how to add this CalendarNotificationTrigger to the trigger of the scheduleNotificationAsync

Also, after looking at typescript more I was able to get this to write to the console using something like this:

const NewCal = (makeCal: CalendarNotificationTrigger) => {
  const month = new Date().getMonth();
  const dayOfMonth = new Date().getDate();

  if (month == makeCal.dateComponents.month) {
    console.log("it is ok")
  } else {
    console.log('no it is not')
  }
}

const trigger = {
  type: 'calendar',
  repeats: false,
  dateComponents: {
    hour: 5,
    month: 7,
    minute: 37,
  }
}

NewCal(trigger);

Notifications.scheduleNotificationAsync({
  content: {
    title: "calendar trigger!",
    body: 'Change sides!',
  },
  
  trigger,
      
});

based on the docs on the API page I should be able to add the variable trigger to the scheduleNotificationAsync method — as seen in this example in the same API docs (where trigger is inserted as the value of the trigger variable):

import * as Notifications from 'expo-notifications';

const trigger = new Date(Date.now() + 60 * 60 * 1000);
trigger.setMinutes(0);
trigger.setSeconds(0);

Notifications.scheduleNotificationAsync({
  content: {
    title: 'Happy new hour!',
  },
  trigger,
});

But I get an error when I attempt to add my trigger object as the value of the trigger key in the scheduleNotificationAsync method.

my goal is to create a local notification based on the current date.

Thank you,

:face_with_head_bandage:

hum…something very strange happened today. I got 45 notifications. I can tell they are from a few days ago because I change the text of the notification every day that I work on this. Why would that happened?

:sweat:

do I need to request permission to send local notifications? Local notifications appeared to be working (based on calendar trigger seen here: Notifications - Expo Documentation) on expo. But when I published my app to test flight I noticed that my app is not listed under “Notifications” in Settings

this means my app has not requested the user to send notifications. Apparently I need this (as seen here: Notifications - Expo Documentation):

async function registerForPushNotificationsAsync() {
  let token;
  if (Constants.isDevice) {
    const { status: existingStatus } = await Permissions.getAsync(Permissions.NOTIFICATIONS);
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      alert('Failed to get push token for push notification!');
      return;
    }
    token = (await Notifications.getExpoPushTokenAsync()).data;
    console.log(token);
  } else {
    alert('Must use physical device for Push Notifications');
  }

  if (Platform.OS === 'android') {
    Notifications.setNotificationChannelAsync('default', {
      name: 'default',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: '#FF231F7C',
    });
  }

in order to send local notifications. I guess it was working on the expo app because the expo app already asked for permission to send notifications?

I am willing to pay someone to help me figure this out.

hey there @notbrent @charliecruzan @wodin just wanted to reach out to see if ya’ll could help? I’ve been stuck on this for 3 months. I want to be fair and not just “ask for someone else to write my code.” I’m really just struggling with this.

I just made a recent push to my github repo: GitHub - vital-tech-results/react-native-app-ekadasi: react native app based on expo CLI

I guess I am supposed to put the “request for permissions” function in componentDidMount in the root of the app?

The confusing part is that I am getting local notifications on my app during development on the expo app. But when I build and publish and test in test flight for iOS it does not prompt to allow permissions and when I look in Settings > Notifications on my iOS device I don’t see my test flight app.

1 Like

@dj-designs sure you can request permissions in componentDidMount, or really anywhere else (as long as you’re requesting before you try to send any important notifications)

Are you saying that when you request permissions in your iOS app with await Permissions.askAsync(Permissions.NOTIFICATIONS), nothing happens?

If you’ve already granted the Expo app permissions to send notifications, you don’t need to ask again, so that would explain why it’s working in the Expo app. I recommended reading our push notifications guide end-to-end, it’s a huge help when implementing notifications into your app

1 Like

@charliecruzan Thank you for the quick reply! Yes, I’ve been reading this push notification documentation for the past few months; after experimenting I concluded that I don’t need all of the push notification code if I am only doing local notifications. Maybe I am wrong?

Yes, that is correct. I have this snippet starting with registerForPushNotificationsAsync from the documentation you cited but nothing happens after I build and send to test flight on ios.

When I install my app (after building the ios version and sending to Test Flight and installing via test flight on my device) then I don’t see a request to “Allow” notifications. Even though during development I am seeing local notifications (only when app is in foreground) based on current date.

I just pushed an update on the Apple Store and when I updated my expo app on my personal ios device it prompted me “do you want this app to send notifications?” So, this is a good sign. I will follow up tomorrow because the way my app is coded I should receive a notification at 3 am tomorrow morning. Hoping for the best! :crossed_fingers:t2:

unfortunately the app did not display any notification.
good sign that at least it asked for permission to display notifications. I think that’s progress…

Has anyone had any luck with local notifications? Calendar-based notifications?

When you ask for permissions, does it return granted? I know that local notifications work, I use them myself and we have the example on the docs page using it. Happy to try and help you figure this out but I’ll need a minimal reproducible demo of your issue so I can help debug :smile:

hey there @charliecruzan apologies for late reply. Thank you for your kind consideration. When you say, “minimal reproducible demo,” does that mean I should strip everything except the page where notifications code is? I have a public github of this project here: GitHub - vital-tech-results/react-native-app-ekadasi: react native app based on expo CLI

The notifications code is on Screens/HomeScreen.js

let me know and I will be happy to push a fresh repo with minimal code to reproduce the issue.

:face_with_head_bandage:

hey there @charliecruzan I got notifications to work when not in foreground by looking carefully at the documentation in development when using expo app on ios.

I am using sDK 39

notifications also work when app is in foreground

this is what I wanted so I made a fresh build, pushed to Apple and used test flight on my device to install the test build. when launching my app for the first time I get a dialogue requesting to allow my app to send notifications; and when I open settings > notifications I see my app listed and activated.

However, notifications do not work; app was not launched. How can I test if notifications work when app is not open at all (not in foreground AND not open)? In order to test I need to have the expo app installed and running and connecting to my app, correct?

I would be grateful for any help. I don’t know what else to do.

Could you be more specific?

  • Do notifications show up in the device at all? If not, check the push receipt.
  • Do notifications show up, but then pressing them doesn’t open the app? I haven’t seen this happen before so please provide a way for me to reproduce that
  • Do notifications show up, and then tapping them opens the app, but then your listeners aren’t triggered? You’ve probably misconfigured something so I would double check your code with the docs

You should be able to test local notifications on a simulator with a simulator build expo build:ios -t simulator, if not then you will need to test via testflight

Hey there thanks for the quick reply.

My situation is this:

  • Do notifications show up in the device at all? If not, check the push receipt.”

But how would I check the push receipt? will I check it on my device somehow?

I recommend reading through all push notification docs first- Push Notifications Overview - Expo Documentation

I thought that since I am using local notifications I didn’t need to send notifications to an external server. I guess I need this step. But why has it been working during development even though I never implemented anything in the docs here: Sending Notifications with Expo's Push API - Expo Documentation

After looking at the docs in the link you provided, I managed to implement the push receipt in my code and console.log a receipt. Now I suppose I could write the response to a log file. But I can’t figure out how to access content of scheduleNotificationAsync; this content would be sent in the request for a receipt instead of hardcoding a message in the body of a json request as seen in the link you provided.

I also see there is a handleError method on the setNotificationHandler; I was thinking that I could put the push receipts code there.

This is what I have for push receipts (but not sure how to input the body: JSON.stringify from my scheduled Notification body:

// first send a push notification with body text
async function getNotifsFromApiAsync() {
  return await fetch('https://exp.host/--/api/v2/push/send', {
    method: 'POST',
    headers: {
      Host: 'exp.host',
      Accept: 'application/json',
      'Accept-Encoding': 'gzip, deflate',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      "to": "ExponentPushToken[in3MwyHdqFTopctcsNwBdI]",
      "title": "hello from ekad app",
      "body": "sent from fetch post"
    })
  })
    .then(response => response.json())
    .then(responseJson => {

      const ticketIdString = responseJson.data.id;
      console.log(ticketIdString)

//this is the post request with the id from the send request above to check for errors
      fetch('https://exp.host/--/api/v2/push/getReceipts', {
        method: 'POST',
        headers: {
          Host: 'exp.host',
          Accept: 'application/json',
          'Accept-Encoding': 'gzip, deflate',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          "ids": [ticketIdString]
        })
      })
        .then(response => response.json())
        .then(receiptJson => {
          console.log('this is receipt json', receiptJson)
        })

      return;
    })
    .catch(error => {
      console.error(error);
    });
}

getNotifsFromApiAsync()