Implementando Push Notification (Android/iOS) no React Native com Amazon SNS
As notificações estão disponíveis na maioria dos nossos dispositivos modernos, tais como smartphones e computadores. Elas são amplamente utilizadas por empresas e aplicativos para trazer novidades ao usuário, informá-lo sobre algo importante ou até mesmo lembrá-lo de realizar determinadas tarefas.
O Push Notification, ou notificações via push, deriva do conceito de “empurrar um lembrete” ou “empurrar um conteúdo” para o usuário. É um recurso que exibe uma janela, pop-up ou até mesmo um retângulo com uma mensagem no seu celular ou navegador. A notificação push é um subgênero de notificação e os usuários sempre são questionados se desejam recebê-las, tornando-as um recurso opcional. Além disso, são mais concisas, apresentando-se como textos curtos ou imagens.
Neste artigo, vamos implementar as configurações para a funcionalidade de notificações dentro do React Native. Nosso objetivo é garantir que o usuário receba notificações no seu smartphone em tempo real.
Para isso, iremos utilizar push notifications, que nos permitem enviar informações e avisos concisos diretamente para o usuário no exato momento em que essas ações são executadas. Para implementar essa funcionalidade, faremos uso do Amazon Simple Notification Service (SNS), estabelecendo a comunicação necessária para integrar com o React Native.
O que é o Amazon SNS?
O Amazon SNS é um serviço que irá realizar as entregas de mensagens para os dispositivos cadastrados em sua plataforma. Isso ocorre de forma assíncrona, quando cadastra o token do dispositivo na plataforma, é obtido um endpoint que faz essa comunicação. Para se aprofundar mais nesse tópico, leia:
Configurando o projeto e instalando as bibliotecas
Pré requisitos para iniciar o projeto:
Para essa documentação foram utilizadas as seguintes versões de bibliotecas:
- Versão mínima do React Native: v0.61.5
- zoOr/react-native-push-notification: v7.4.0
- react-native-community/push-notification-ios: v1.10.1
Vamos iniciar nosso desenvolvimento criando e configurando nosso projeto.
No terminal, crie um aplicativo React Native em branco:
npx react-native init reactNativePushNotificationSNS
Com o projeto criado, devemos entrar no diretório criado:
cd reactNativePushNotificationSNS
Para começar com o push notification no aplicativo feito com React Native, será necessário a instalação de duas bibliotecas, uma para Android e a outra para iOS.
Abaixo, você encontrará os links para os repositórios do GitHub das bibliotecas utilizadas:
React-native-push-notification (android)
React-native-push-notification/ios
Download das bibliotecas
Então como visto acima, será necessário instalar as bibliotecas dentro do projeto:
// android
yarn add react-native-push-notification
// iOS
yarn add @react-native-community/push-notification-ios
Como realizar a configuração no Android?
No arquivo android/app/src/main/AndroidManifest.xml
, é necessário adicionar as seguintes linhas para habilitar permissões para o aplicativo e vincular os módulos da biblioteca react-native-push-notification:
<!-- android/app/src/main/AndroidManifest.xml -->
...
<!-- adiciona as duas linhas abaixo fora do application -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
…
<application ...>
<!-- dentro do application adicione as linhas abaixo -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="true"/>
<meta-data android:name="com.dieam.reactnativepushnotification.channel_create_default" android:value="false"/>
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
...
Para que aconteça a comunicação entre a Amazon SNS e o dispositivo é necessário um intermediário entre eles, no caso do Android precisa do Firebase para que isso aconteça, é necessário realizar a configuração inicial da biblioteca do próprio Firebase, então aplique o setup de configuração inicial, igual segue no link abaixo:
Agora, é necessário realizar a vinculação da biblioteca react-native-push-notification ao projeto. Isso pode ser feito de duas formas; Automaticamente, através do comando react-native link
, ou manualmente:
Manualmente:
Em android/setting.gradle
, adicione as seguintes linhas:
// android/settings.gradle
...
include ':react-native-push-notification'
project(':react-native-push-notification').projectDir = file('../node_modules/react-native-push-notification/android')
E no arquivo android/app/build.gradle
a implementação da biblioteca:
// android/app/build.gradle
dependencies {
...
implementation project(':react-native-push-notification')
...
}
Como último passo, importe o pacote da biblioteca dentro do arquivo MainApplication.java
, ao final da lista de importações:
// MainApplication.java
...
import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;
Como realizar a configuração no iOS?
O mesmo deve ser feito para a versão do RN >= 0.60. No build do projeto para o iOS é adicionado automaticamente as dependências nativas da biblioteca assim que instalado a biblioteca, porém, caso queira realizar manualmente ou possua versões do RN anteriores a 0.60, rode o comando abaixo:
react-native link @react-native-community/push-notification-ios
Agora na pasta iOS dentro do projeto, é preciso adicionar o suporte para notificações, primeiro no arquivo AppDelegate.h
:
// AppDelegate.h
...
#import <UserNotifications/UNUserNotificationCenter.h>
// altere a linha com @interface para a linha abaixo:
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
No arquivo AppDelegate.m
adicione as seguintes importações no topo do arquivo:
// AppDelegate.m
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
Dentro do escopo do application didFinishLaunchingWithOptions
e antes do return Yes;
, adicione a seguinte linha explícita com o comentário:
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
// Adicione a linha abaixo: UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
Adicione também a função abaixo para receber notificações em primeiro plano:
// AppDelegate.m
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))
completionHandler
{
completionHandler(UNNotificationPresentationOptionSound |
UNNotificationPresentationOptionAlert |
UNNotificationPresentationOptionBadge);
}
O último passo dentro do código nativo do iOS, antes da função — (NSURL*)sourceURLForBridge:(RCTBridge *)bridge
, adicione o código abaixo, para funcionar o registro do token do dispositivo e as notificações locais:
// AppDelegate.m
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
} - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
Para finalizar a configuração, é necessário adicionar o Capabilities para o dispositivo, então no XCode abra o projeto para iOS e em target adicione Push Notifications e Background Modes (opções: Remote Notifications e Background Fetch).
Ícones para as notificações
iOS somente será preciso configurar/adicionar imagens no AppIcon dentro do XCode na dimensão correta para o “iphone notification”.
Para Android é preciso entender que os ícones precisam ser totalmente brancos e com detalhes em transparência, de acordo com a google, com a cor selecionada no arquivo AndroidManifest.xml
com a linha de código logo abaixo, dessa forma, a cor atinge os pixels brancos necessário para dar cor ao ícone. Para entender melhor leia o artigo no conteúdo destacado:
A cor que preencherá o conteúdo branco do seu ícone deve ser adicionado no arquivo colors.xml
na pasta res/values
caso não exista esse arquivo, deverá ser criado no mesmo caminho informado:
<!-- android/app/src/values/colors.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorNotification">#000000</color>
</resources>
E dentro do AndroidManifest.xml
dentro do escopo de application
:
<!-- android/app/src/main/AndroidManifest.xml -->
<application ...>
...
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@mipmap/ic_notification" />
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@color/colorNotification"/>
...
</application>
Aqui também tem a issue na biblioteca sobre o ícones de notificações no Android:
Como configurar no React Native?
Nos arquivos do React Native, é preciso configurar o Push Notification utilizando os métodos da biblioteca e adaptá-los de acordo com a sua necessidade. É preciso que a configuração seja feita fora de um componente React para funcionar adequadamente, o melhor é ser adicionado dentro do index.js
na raiz do projeto.
// ./index.js
import PushNotification, { Importance } from 'react-native-push-notification';
import PushNotificationIOS from '@react-native-community/push-notification-ios';
PushNotification.configure({
onRegister: notificationData => {
// metódo para registrar o token do dispositivo
},
onNotification: notification => {
// método que recebe as notificações remotas
// necessário a linha abaixo para o iOS
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
// NECESSÁRIO PARA O ANDROID OBTER COMUNICAÇÃO COM O FIREBASE
senderID: FIREBASE_SENDER_ID,
permissions: {
alert: true,
badge: true,
sound: true,
},
popInitialNotification: true,
requestPermissions: true,
smallIcon: 'ic_notification',
largeIcon: 'ic_launcher',
});
Com Android é necessário criar um canal de notificação, com o PushNotification pode chamar o método createChannel
, e também pode ser implementado dentro do index.js
PushNotification.createChannel({
channelId: 'channelId',
channelName: 'channelName',
playSound: false,
soundName: 'default',
importance: Importance.HIGH,
vibrate: true,
});
Neste link, explica o por que é necessário criar canais de notificações para o Android:
Com isso as notificações remotas já funcionarão para iOS e para Android. Agora só precisará criar a lógica de envio para o back-end armazenar as informações de token, sistema operacional do dispositivo do qual está sendo enviado e qualquer outra informação necessária que você precise utilizar para conseguir criar uma comunicação entre Amazon SNS e o dispositivo do usuário.
Configuração do Firebase com o Push Notification
Então para o Android como visto acima foi necessário configurar inicialmente o Firebase dentro do app/build.gradle
; Mas para isso funcionar é preciso ser feito a instalação da biblioteca @react-native-firebase/app
e o cadastro na plataforma do Firebase do seu aplicativo. Após isso, com o arquivo do google-services.json
em mãos, adicione dentro da pasta android/app
. No link abaixo tem uma explicação de como realizar a instalação completa:
https://rnfirebase.io/#installation
Após a configuração inicial será preciso adquirir a server Key, que se encontra nas configurações do projeto do Firebase na aba Cloud Messaging, e copiar o valor da chave do servidor (server key). Caso não exista será necessário adicionar:
Configuração da Amazon SNS para o Android
Vamos partir para o Amazon AWS, no serviço de SNS (Simple Notification Service), no menu de notificações por push, deverá criar um aplicativo de plataforma para o Android
Para criar o aplicativo de plataforma, deverá ser escolhido um nome para o aplicativo e a plataforma será o Firebase Cloud Messaging (FCM) para que seja adicionada a chave de servidor do Firebase que mostrei logo acima
Com isso feito, já é possível disparar mensagens por push notification através do Amazon SNS, sendo necessário somente o token de um dispositivo Android, que você pode obter pelo método onRegister mostrado na configuração da biblioteca no React Native.
Configuração do Apple Developer com o Push Notification
Para iniciar a configuração da Apple, certifique-se que o projeto já está configurado dentro da loja Apple Store e que já possui perfil para o aplicativo na Apple Developer Account.
Em Apple Developer no menu Account, entre em Certificates, Identifiers e Profiles, e logo em seguida acesse Identifiers, selecione o seu aplicativo que irá receber o push notification. Agora basta marcar a opção Push Notification na lista de Capabilities, e configurar os certificados
Para o funcionamento do push notification no iOS é necessário gerar o arquivo de certificado que vai habilitar a comunicação do serviço de notificação, o link abaixo explica como criar o arquivo CSR da Apple no aplicativo KeyChains do macbook (Só há possibilidade de criar com um macbook):
Com arquivo adicionado, ainda nas configurações do Push Notification, é preciso adicionar na seção de Production SSL Certificate o arquivo que acabou de gerar no formato CSR:
Agora vamos converter o arquivo CSR para .p12
, que será utilizado no SNS. Para isso adicione seu arquivo CSR no aplicativo KeyChain do macbook (pode simplesmente arrastar o arquivo até o programa), e assim que adicionado, clique com o botão direito do mouse em cima do certificado e selecione a opção Exportar para criar o arquivo .p12
:
Configurando Amazon SNS para o iOS
Então com o arquivo .p12
em mãos, basta adicionar um aplicativo de plataforma na SNS para iOS. Para isso na Plataforma de notificações, selecione a opção Apple iOS, selecione Serviço Push para iOS e adicione o arquivo .p12
e caso possua senha, adicione também
Pontos de atenção sobre o funcionamento do Push Notification para Android e iOS:
Somente para o Android é possível testar com emulador as notificações remotas e locais, e com iOS é possível ver notificações locais utilizando as funções da biblioteca dentro do aplicativo, mas não é possível gerar token no emulador para notificações remotas.