Gabul
7 min readMar 7, 2019

Push Notifications - Flutter com OneSignal.

O mais usado recentemente para push é o firebase, devido a sua alta integração com o Flutter, mas nesse artigo irei apresentar uma forma mais descomplicada ainda de enviar push notifications. A plataforma se chama OneSignal.

O OneSignal é uma plataforma que se comunica com o firebase para fazer o push, nele é possível ainda utilizar o crashlytics. Então, neste artigo iremos fazer a comunicação com o OneSignal e o App em flutter.

Primeiro passo

Acessar o site do OneSignal e criar uma conta.

Segundo passo

Criar uma conta no Firebase ou usar a sua existente.

Terceiro passo

Agora com as duas contas criadas, vamos criar um app no Firebase e outro no OneSignal.

Firebase

Acesse o console e adicione um projeto com o seu nome de preferência.

Projeto criado, vamos acessar a parte de configurações e navegar para Cloud Messaging.

Nesta parte, iremos necessitar da Chave do servidor e do código do remetente, deixe isso aberto e vamos para o passo seguinte, a criação de um app no OneSignal.

OneSignal

Logue no sistema e clique em ADD APP, coloque um nome de sua preferência.

Escolha em seguida a plataforma Android.

Agora iremos colocar as duas keys do Firebase mencionadas anteriormente.

Pressione save e escolha Native Android.

Finalizando tudo certo, irá ficar nesta página.

Your App ID será a key usada no seu app flutter para identificar seu aplicativo. Então deixe isso aberto no navegador pois iremos utilizar.

Concluímos as configurações básicas, agora iremos colocar a mão na massa, com o aplicativo.

Daqui em diante fica a sua escolha, de criar um app novo ou usar em um projeto existente.

Android Studio

Agora com nosso projeto criado no Android Studio, iremos então adicionar o plugin onesignal_flutter no pubspect.yaml

name: flutteronesignal
description: Desenvolvido por Gabriel Savio, CEO da Grape DEV

version: 1.0.0+1

environment:
sdk: ">=2.1.0 <3.0.0"

dependencies:
flutter:
sdk: flutter

cupertino_icons: ^0.1.2
onesignal_flutter: any
dev_dependencies:
flutter_test:
sdk: flutter

flutter:

uses-material-design: true

Agora precisamos configurar os arquivos do android.

Primeiro arquivo: android/build.gradle

Vamos adicionar a seguinte linha:

buildscript {
repositories {
// ...
maven { url 'https://plugins.gradle.org/m2/' } // Gradle Plugin Portal
}
dependencies {
// ...
// OneSignal-Gradle-Plugin
classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.1, 0.99.99]'
}
}

Ficando da seguinte forma:

buildscript {
repositories {
google()
jcenter()
maven { url 'https://plugins.gradle.org/m2/' }
}

dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.1, 0.99.99]'
}
}

allprojects {
repositories {
google()
jcenter()
}
}

rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
delete rootProject.buildDir
}

Agora vamos em outro arquivo, no seguinte : android/app/build.gradle e no final dele iremos colar a seguinte linha:

apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'

Ficando da seguinte forma:

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 28

lintOptions {
disable 'InvalidPackage'
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "grapedev.com.flutteronesignal"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}

flutter {
source '../..'
}

dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'

Pronto! Temos tudo configurado para receber o código no flutter para inicializar o OneSignal.

Flutter

Agora vamos para o código no flutter. Iremos criar a estrutura de pastas e arquivos seguintes na imagem:

Obs: ignore.dart é para ser ignorado mesmo, não precisa criar ele.

Nossa arquivo main.dart ficou da seguinte forma:

import 'package:flutter/material.dart';
import 'package:flutteronesignal/pages/home_page.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter One Signal',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}

e nossa pages/home/home_page.dart

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("FlutterOneSignal"),
centerTitle: true,
),
body: Column(children: <Widget>[
Text("Notificações")
],),
);
}
}

Com nosso app da seguinte forma.

Agora iremos criar o nosso BlocHome (pages/home/bloc/home_bloc.dart) para iniciar o OneSignal.

import 'package:onesignal/onesignal.dart';

class BlocHome{

void initOneSignal(){
OneSignal.shared.init("your_onesignal_app_id_here");
}

}

Agora volte no site do OneSignal e copie o APPID e cole ai.

Ficando assim:

import 'package:onesignal/onesignal.dart';

class BlocHome{

void initOneSignal(){
OneSignal.shared.init("bc2472d1-fac8-433f-be56-48ea9ecbc1ef");
}

}

obs: Lembre-se de trocar para o seu appID, para conseguir visualizar pelo painel do OneSignal.

Agora precisamos importar esse BlocHome na nossa HomePage e chamar o método initOneSignal no void init, ficando da seguinte forma:

import 'package:flutter/material.dart';
import 'package:flutteronesignal/pages/home/bloc/bloc_home.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

var bloc = BlocHome();

@override
void initState() {
bloc.initOneSignal();
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("FlutterOneSignal"),
centerTitle: true,
),
body: Column(children: <Widget>[
Text("Notificações")
],),
);
}
}

Feito isso, agora vamos testar! Dê stop no seu projeto, e compile ele novamente.

Feito isso, vamos ao site do OneSignal, se tudo estiver corrido certo, vai aparecer que seu app tem 1 usuário.

Agora, vamos enviar um push, clique em MESSAGES, procure por NEW PUSH.

Escreva um título e uma message só para teste.

Role até o final e clique em CONFIRM.

Agora é só enviar!

Pronto funcionou! Agora vem a pergunta. Porque apareceu esse popUp feio na minha tela? O onesignal tem um disparador de notificação interno caso o app esteja em primeiro plano, você pode desativar isso com o seguinte código.

OneSignal.shared.setInFocusDisplayType(OSNotificationDisplayType.none);

Adicione ele no initOneSignal.

import 'package:onesignal/onesignal.dart';

class BlocHome{

void initOneSignal(){
OneSignal.shared.init("bc2472d1-fac8-433f-be56-48ea9ecbc1ef");
OneSignal.shared.setInFocusDisplayType(OSNotificationDisplayType.none);
}


}

E se o app estiver em segundo plano? Funciona, faça o teste.

E se o app estiver fechado? Também funciona.

O onesignal tem algumas funções interessantes, podendo identificar cada usuário no seu app por email, e ainda pode enviar TAGS para facilitar na segmentação de usuários para enviar um push específico para um somente ou para um grupo.

As funções sao as seguintes:

//Identifica o user por email
OneSignal.shared.setEmail();
//Identifica po um idExterno, id de sua API
OneSignal.shared.setExternalUserId(externalId);
//Envia somente uma tag
OneSignal.shared.sendTag(key, value);
//Enviar várias tags
OneSignal.shared.sendTags(tags);
//Pegar as tags do usuário
OneSignal.shared.getTags();

E também pode utilizar o método abaixo, para pegar a chegada de notificações e tomar decisões dentro do seu app.

OneSignal.shared.setNotificationReceivedHandler((OSNotification notification) {

});

No próximo artigo eu irei implementar a função citada acima, para criar um sistema de notificações interno no aplicativo, um histórico de notificações que já recebeu.

Vou deixar abaixo o link da documentação oficial do OneSignal .

Documentação Oficial do OneSignal sobre Flutter

Segue link do projeto no GitHub

https://github.com/gabulsavul/flutteronesignal