npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@uplift-ltd/push-notifications

v5.0.0

Published

push-notifications

Downloads

8

Readme

@uplift-ltd/push-notifications

Installation

npm i --save @uplift-ltd/push-notifications

Firebase Cloud Messaging (FCM)

FCM is required for sending push notifications to Android devices. See Expo docs.

  • Add Project in Firebase Console
  • Add Firebase to your Android app and follow the setup steps. Make sure that the Android package name you enter is the same as the value of android.package in your app.config.*.ts
  • Download the google-services.json file and place it in src/constants/google-services/google-services-*.json
  • In your app.config.*.ts, add an android.googleServicesFile field with the relative path to the google-services.json file you just downloaded.
{
  ...
  "android": {
    "googleServicesFile": "./src/constants/google-services/google-services-production.json",
    ...
  }
}

API

This module can used either with context or hooks.

Note: When reading the docs below, pay attention to the difference between these:

  • registerForPushNotifications -> this is a function you can pass in to customize getting the token
  • registerPushNotifications -> this is a function you get back to trigger getting the token
  • onRegisterPushNotifications -> this is a callback when registerPushFunction resolves

NotificationProvider

Takes in functions to handle:

  • notification received
  • notification response received
  • save token / register device
import {
  NotificationProvider,
  NotificationReceivedListener,
  NotificationResponseReceivedListener,
} from "@uplift-ltd/push-notifications";
import Constants from 'expo-constants

const handleNotificationReceived: NotificationReceivedListener = (notification) => {
  console.log(notification);
};

const handleNotificationResponseReceived: NotificationReceivedListener = (response) => {
  console.log(response.notification);
};

function Root() {
  const [registerDevice] = useMutation(REGISTER_DEVICE);

  const handleRegisterPushNotifications = useCallback(async (token) => {
    try {
      await registerDevice({ variables: { token, deviceId: Constants.installationId } });
    } catch (err) {
      Sentry.captureExeception(err)
    }
  }, []);

  return (
    <NotificationProvider
      onReceived={handleNotificationReceived}
      onResponseReceived={handleNotificationResponseReceived}
      onRegisterPushNotifications={handleRegisterPushNotifications}
    >
      <App />
    </NotificationProvider>
  );
}

NotificationPrompt

On render, prompts the user for permission to send notifications. Uses context from NotificationProvider.

import { NotificationProvider, NotificationPrompt } from "@uplift-ltd/push-notifications";

function Root() {
  return (
    <NotificationProvider {...seePropsAbove}>
      <NotificationPrompt />
    </NotificationProvider>
  );
}

NotificationAlertPrompt

If permission is undetermined, it renders an alert. If the user accepts, then it requests permission to notify. On iOS if the user denies you cannot ask for permission again. You can customize the alert copy, defaults are shown below.

NOTE: On iOS if the user denies the status is always undetermined, you may want to store if the user denied and hide the component. You can do this using onRegisterPushNotifications on NotificationProvider or onRegisterPushNotifications on NotificationAlertPrompt. In the future we will handle this here. Note that onRegisterPushNotifications should be a stable function (should not change on render).

import { NotificationProvider, NotificationAlertPrompt } from "@uplift-ltd/push-notifications";

function Root() {
  return (
    <NotificationProvider {...seePropsAbove}>
      <NotificationAlertPrompt
        title="Please Allow Notifications"
        message="This application uses notifications to keep you up to date on new activity."
        acceptLabel="Enable"
        cancelLabel="Not Now"
      />
    </NotificationProvider>
  );
}

NotificationRenderPrompt

If permission is undetermined, it renders the children. The children is a function that gets passed in permissionStatus and registerPushNotifications.

NOTE: On iOS if the user denies the status is always undetermined, you may want to store if the user denied and hide the component. You can check the result of registerPushNotifications for this.

import {
  NotificationProvider,
  NotificationRenderPrompt,
  PermissionStatus,
} from "@uplift-ltd/push-notifications";

function Root() {
  return (
    <NotificationProvider {...seePropsAbove}>
      <NotificationRenderPrompt>
        {({ permissionStatus, registerPushNotifications }) => {
          if (permissionStatus !== PermissionStatus.UNDETERMINED) {
            return null;
          }
          return <Button onPress={registerPushNotifications}>Notify Me!</Button>;
        }}
      </NotificationRenderPrompt>
    </NotificationProvider>
  );
}

usePushNotifications

You can avoid the context entirely and use the hooks instead.

import { usePushNotifications, PermissionStatus } from "@uplift-ltd/push-notifications";

const handleNotificationReceived: NotificationReceivedListener = (notification) => {
  console.log(notification);
};

const handleNotificationResponseReceived: NotificationReceivedListener = (response) => {
  console.log(response.notification);
};

function Root() {
  const { permissionStatus, registerPushNotifications } = usePushNotifications({
    onReceived: handleNotificationReceived,
    onResponseReceived: handleNotificationResponseReceived,
    onRegisterPushNotifications: async ({ token }) => {
      if (token) {
        const { data } = await registerDevice({
          variables: { token, deviceId: Constants.installationId, userId },
        });
        if (!data.registerDevice.success) {
          throw new Error(
            data.registerDevice.message || "Failed to register for push notifications."
          );
        }
      }
    },
  });

  const [registerDevice] = useMutation(REGISTER_DEVICE);

  useEffect(() => {
    const run = async () => {
      try {
        if (permissionStatus === PermissionStatus.UNDETERMINED) {
          const { token } = await registerPushNotifications();
          if (!token) {
            Alert.alert("If you change your mind you can go to app settings.");
          }
        }
      } catch (err) {
        Sentry.captureExeception(err);
      }
    };
    run();
  }, [userId]);
}