Visualizzazione post con etichetta Firebase. Mostra tutti i post
Visualizzazione post con etichetta Firebase. Mostra tutti i post

giovedì 22 dicembre 2016

Leggere dati da Firebase Realtime Database

Per me che vengo da una esperienza SQL mettere le mani per la prima volta su un Database NoSql come quello di Firebase e' un po' spiazzante....ma ci si fa l'abitudine

Per prima cosa Firebase non gestisce i dati mentre tabelle bidimensionali a struttura rigida ma i dati vengono rapppresentati come un albero a cui sono attaccate delle derivazioni (child) i quali non e' necessario che abbiamo la stessa struttura (al di sotto di una chiave, per esempio, in un caso le proprieta' possono essere due oppure tre)


Se si editano i dati dalla Console di Firebase si vedra' che posizionando il mouse sulla root appaiono dei simboli (+ e -)..la prima volta che si usa sembra che non si abbia nessuna interazione perche' i simboli scompaiono appena si sposta il mouse



Oltre a creare i dati in modo interattivo si possono ovviamente creare anche via codice. Di seguito un esempio in Javascript commentato con le righe evidenziate in giallo
----------------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8 />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Read</title>

  <!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.6.4/firebase.js"></script>



</head>
<body>

<pre id="punti">

</pre>

<script>
  // Initialize Firebase

  var config = {
    apiKey: "AIzaSyAchx8oVeLUgxxxxxxxxxxxxxxxxxxxxxxx",
    authDomain: "notifica-23425.firebaseapp.com",
    databaseURL: "https://notifica-23425.firebaseio.com",
    storageBucket: "notifica-23425.appspot.com",
    messagingSenderId: "392xxxxxxxxxxxxxx"
  };
  firebase.initializeApp(config);


  var timestamp = new Date().getTime();
  console.log(timestamp);

  //vengono inseriti due nodi nella radice
  // usando il comando set vengono di fatto rimossi tutti i contenuti nel db
  var ins_punti = firebase.database().ref();

  ins_punti.set({
        l2: {
          lat: 1,
          lon: 30,
          nome: "Venezia",
          tempo: timestamp
        },
        l3: {
          lat: 33,
          lon: 40,
          nome: "Bari"
        }
      });

  //vengono aggiunti al nodo Punti due elementi. Si tratta di un append
  // e viene quindi di default inserita una chiave univoca
  ins_punti.child("Punti").push({
              lat: 13,
              lon: 33,
              nome: "Torino"
          });

  ins_punti.child("Punti").push({
                      lat: 14,
                      lon: 35,
                      nome: "Firenze"
                  });


  //vengono mostrate a video tutte le coppie del ramo "l2" del nodo in radice
  const prePunti = document.getElementById('punti');
  const dbRefPunti = firebase.database().ref().child('l2');
  dbRefPunti.on('value', snap => {
              prePunti.innerText = JSON.stringify(snap.val(),null,1);

  //con questa chiamata vengono richieste tutte le coppie chiave/valore del ramo Punti
  //da qui in poi i risultati sono visibili nel log e non a video
  firebase.database().ref().child('Punti').on('value', snap => console.log(snap.val()));

  //con questa chiamata vengono richieste tutte le coppie chiave/valore dell'ultimo nodo aggiunto alla lista del ramo Punti
  firebase.database().ref().child('Punti').limitToLast(1).on('child_added', snap => console.log(snap.val()));

  //con questa chiamata viene richiesto il valore del campo nome dell'ultimo nodo aggiunto alla lista del ramo Punti
  firebase.database().ref().child('Punti').limitToLast(1).on('child_added', snap => console.log(snap.val().nome));

  //con questa chiamata viene richiesto il valore del campo nome del nodo con lat=13 del ramo Punti
  firebase.database().ref().child('Punti').orderByChild("lat").equalTo(13).on('child_added', snap => console.log(snap.val().nome));

  firebase.database().ref().child('l2').update({lat: 133});

  //rimuove il ramo l1 dalla root
  firebase.database().ref().child('l3').remove();
});



</script>

</body>
</html>
----------------------------------------------------------------

La cosa interessante e' che le modifiche effettuate risultano essere in realtime. Se ci sono differenti client con la pagina Web aperta ed una modifica e' stata effettuata al DB questa sara' visualizzata su tutti i client senza la necesssita' di ricarica la pagina

Come per i db sql anche per Firebase e' possibile inserire la definizione delle chiavi per accelerare la ricerca e si possono definire le regole di accesso. Cio' viene effettuato nel Tab regole o rules













martedì 20 dicembre 2016

Hosting su Firebase con Centos 7

Firebase offre la possibilita' di avere anche un hosting di contenuti statici (quindi si puo' utilizzare scripting lato client ma non scripting lato server...niente PHP)

Per sfruttare tale opzione si utilizza Firebase-CLI via NPM. Si parte su Centos 7 installando NPM mediante il comando

curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -

e

yum install -y nodejs

a questo punto si installa Firebase-CLI con 

npm install -g firebase-tools
si effettua il login

firebase login (si apre una pagina del browser per l'autenticazione anche a due vie)



ci si sposta nella root del progetto HTML che si vuole pubblicare su Firebase e si digita

firebase init

(vengono creati alcuni file tipo firebase.json e .firebaserc)

di default viene creata una directory public....si copiano qui tutti i file HTML, CSS, JS etc



a questo punto si digita

firebase deploy




ed i file saranno copiati sui server di Firebase e saranno disponibili all'indirizzo

https://{nome_progetto}.firebaseapp.com

prima di fare il deploy l'applicazione Web puo' essere provata usando il comando

firebase serve

sara' avviato un server web locale all'indirizzo 

http://localhost:5000

la gestione dei file sull'hosting avviene in un modo piu' simile a GitHub che a FTP. In pratica si fa un commit di tutti i file ed il server mette in produzione l'ultimo snapshot. Se si e' commesso un errore su un file non si puo' modificare il singolo file ma si deve fare il commit di tutto il progetto

Se si vuole ritornare ad una situazione precedente sicuramente funzionante si puo' selezionare il salvataggio preferito dal tab hosting




Spam su Firebase

Giusto ieri stavo giocando con l'autenticazione Web di Firebase.
Si tratta di un sistema piuttosto semplice. Prima si copia il codice Javascript con i codici di accesso e li si inserisce nella pagina HTML di login




Per prima cosa ho modificato la pagina di tutorial eliminando la possibilita' di registrarsi con la mail. L'idea e' che l'amministratore inserisce a mano gli utenti che possono loggarsi eliminando gli accessi anonimi
Questa e' la pagina di login ed il relativo codice (in giallo nel codice i comandi per l'autenticazione con Firebase)

email3.html
-------------------
<!DOCTYPE html>
<!--
Copyright (c) 2016 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
  <meta charset=utf-8 />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Email/Password Authentication Example</title>

  <!-- Material Design Theming -->
  <link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.orange-indigo.min.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <script defer src="https://code.getmdl.io/1.1.3/material.min.js"></script>

  <link rel="stylesheet" href="main.css">

  <!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.6.4/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "AIzaSyAchx8oVeLUgYnGujAXXXXXXXXXXXXXXX",
    authDomain: "notifXXXXXXXXX.firebaseapp.com",
    databaseURL: "https://notiXXXXXXXX.firebaseio.com",
    storageBucket: "notifXXXXXXX.appspot.com",
    messagingSenderId: "392XXXXXXXX"
  };
  firebase.initializeApp(config);
</script>

  <script type="text/javascript">

    /**
     * Handles the sign in button press.
     */
    function toggleSignIn() {
      if (firebase.auth().currentUser) {
        // [START signout]
        firebase.auth().signOut();
        // [END signout]
      } else {
        var email = document.getElementById('email').value;
        var password = document.getElementById('password').value;

        // Sign in with email and pass.
        // [START authwithemail]
        firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // [START_EXCLUDE]
          if (errorCode === 'auth/wrong-password') {
            alert('Wrong password.');
          } else {
            alert(errorMessage);
          }
          console.log(error);
        });
      }
    }


    function initApp() {
      firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
          window.location.href = "email3.html";
        }
      });
 document.getElementById('quickstart-sign-in').addEventListener('click', toggleSignIn, false);
    }

    window.onload = function() {
      initApp();
    };
  </script>
</head>
<body>
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-header">

  <!-- Header section containing title -->
  <header class="mdl-layout__header mdl-color-text--white mdl-color--light-blue-700">
    
  </header>

  <main class="mdl-layout__content mdl-color--grey-100">
    <div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">

      <!-- Container for the demo -->
      <div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
        <div class="mdl-card__title mdl-color--light-blue-600 mdl-color-text--white">
          <h2 class="mdl-card__title-text">Firebase Email &amp; Password Authentication</h2>
        </div>
        <div class="mdl-card__supporting-text mdl-color-text--grey-600">
          <p>Enter an email and password below and either sign in to an existing account or sign up</p>

          <input class="mdl-textfield__input" style="display:inline;width:auto;" type="text" id="email" name="email" placeholder="Email"/>
          &nbsp;&nbsp;&nbsp;
          <input class="mdl-textfield__input" style="display:inline;width:auto;" type="password" id="password" name="password" placeholder="Password"/>
          <br/><br/>
          <button class="mdl-button mdl-js-button mdl-button--raised" id="quickstart-sign-in" name="signin">Sign In</button>
        

          
        </div>
      </div>

    </div>
  </main>
</div>
</body>
</html>
-------------------


Se l'autenticazione e' corretta allora passa automaticamente alla pagina 2. Se si accede direttamente alla pagina 2 senza autenticazione questa rimanda indietro alla pagina di login.


email3.html
------------------
<!DOCTYPE html>
<!--
Copyright (c) 2016 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
  <meta charset=utf-8 />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Email/Password Authentication Example</title>

  <!-- Material Design Theming -->
  <link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.orange-indigo.min.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <script defer src="https://code.getmdl.io/1.1.3/material.min.js"></script>

  <link rel="stylesheet" href="main.css">

  <!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.6.4/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "AIzaSyAchx8oVeLUgYnGujAEfXXXXXXXXXXXXX",
    authDomain: "XXXXXXXXX.firebaseapp.com",
    databaseURL: "https://XXXXXXXX5.firebaseio.com",
    storageBucket: "XXXXXXXXX.appspot.com",
    messagingSenderId: "39272XXXXXXXX"
  };
  firebase.initializeApp(config);
</script>


  <script type="text/javascript">

    /**
     * Handles the sign in button press.
     */
    function toggleSignIn() {
      if (firebase.auth().currentUser) {
        // [START signout]
        firebase.auth().signOut();
         window.location.href = "email2.html";
        // [END signout]
      } else {
        var email = document.getElementById('email').value;
    
        // Sign in with email and pass.
        // [START authwithemail]
        firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // [START_EXCLUDE]
          if (errorCode === 'auth/wrong-password') {
            alert('Wrong password.');
          } else {
            alert(errorMessage);
          }
          console.log(error);
          document.getElementById('quickstart-sign-in').disabled = false;
          // [END_EXCLUDE]
        });
        // [END authwithemail]
      }
      document.getElementById('quickstart-sign-in').disabled = true;
    }


    /**
     * initApp handles setting up UI event listeners and registering Firebase auth listeners:
     *  - firebase.auth().onAuthStateChanged: This listener is called when the user is signed in or
     *    out, and that is where we update the UI.
     */
    function initApp() {
      // Listening for auth state changes.
      // [START authstatelistener]
      firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
          // User is signed in.
          var displayName = user.displayName;
          var email = user.email;
          var emailVerified = user.emailVerified;
          var photoURL = user.photoURL;
          var isAnonymous = user.isAnonymous;
          var uid = user.uid;
          var providerData = user.providerData;
          // [START_EXCLUDE silent]
          document.getElementById('quickstart-sign-in-status').textContent = 'Signed in';
          document.getElementById('quickstart-sign-in').textContent = 'Sign out';
          document.getElementById('quickstart-account-details').textContent = JSON.stringify(user, null, '  ');
          // [END_EXCLUDE]
        } else {
              window.location.href = "email2.html";
        }
      });
      // [END authstatelistener]

      document.getElementById('quickstart-sign-in').addEventListener('click', toggleSignIn, false);
    }

    window.onload = function() {
      initApp();
    };
  </script>
</head>
<body>
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-header">

  <!-- Header section containing title -->
  <header class="mdl-layout__header mdl-color-text--white mdl-color--light-blue-700">
    <div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
      <div class="mdl-layout__header-row mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--8-col-desktop">
        <a href="/"><h3>Firebase Authentication</h3></a>
      </div>
    </div>
  </header>

  <main class="mdl-layout__content mdl-color--grey-100">
    <div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">

      <!-- Container for the demo -->
      <div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
        <div class="mdl-card__title mdl-color--light-blue-600 mdl-color-text--white">
          <h2 class="mdl-card__title-text">Firebase Email &amp; Password Authentication</h2>
        </div>
        <div class="mdl-card__supporting-text mdl-color-text--grey-600">
          <button class="mdl-button mdl-js-button mdl-button--raised" id="quickstart-sign-in" name="signin">Sign In</button>
          &nbsp;&nbsp;&nbsp;

          <!-- Container where we'll display the user details -->
          <div class="quickstart-user-details-container">
            Firebase sign-in status: <span id="quickstart-sign-in-status">Unknown</span>
            <div>Firebase auth <code>currentUser</code> object value:</div>
            <pre><code id="quickstart-account-details">null</code></pre>
          </div>
        </div>
      </div>

    </div>
  </main>
</div>
</body>
</html>
------------------

Stamani riprendendo in mano la cosa mi sono accorto di un nuovo utente che si era registrato (vedi l'ultima riga della tabella sottostante) senza nessun intervento. Visto che i codici di autenticazione sono inclusi in Javascript e non sono mascherabili e' abbastanza semplice fare un codice HTML che crei un login anonimo via email



a quanto pare non e' possibile limitare questo comportamento. L'unica possibilita' di filtro e' a livello di permessi di accesso alla base dati






venerdì 2 dicembre 2016

Notifiche cloud con Firebase su IOS

Nel precedente post era stato mostrato come inviare notifiche push a client Android tramite il cloud di Firebase. Si puo' fare la stessa cosa anche con IOS ma e' un inferno  e rimando al video linkato



dopo aver creato un progetto generico per prima cosa si devono aggiungere le librerie via Firebase
inizializzando Cocoapod

pod init

poi si edita il Podfile
----------------------------------
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'Notifica' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!


  # Pods for Notifica

  target 'NotificaTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'NotificaUITests' do
    inherit! :search_paths
    # Pods for testing
  end

pod 'Firebase'
pod 'Firebase/Messaging'
end
----------------------------------
poi si installano le librerie

pod install

e si apre il progetto

open Notifica.xcworkspace

per attivare le notifiche e' sufficiente modificare AppDelegate.m (in giallo sono selezionate le righe di interesse)

AppDelegate.m
-----------------------------------
//
//  AppDelegate.m
//  Notifica
//
//  Created by Luca Innocenti on 30/11/16.
//  Copyright © 2016 Luca Innocenti. All rights reserved.
//

#import "AppDelegate.h"
@import Firebase;
@import FirebaseMessaging;


@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [FIRApp configure];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tokenRefreshCallback:) name: kFIRInstanceIDTokenRefreshNotification object:nil];
    
    UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
    [application registerUserNotificationSettings:settings];
    [application registerForRemoteNotifications];
    
     return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    
    [[FIRMessaging messaging]disconnect];
    
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    [self connectToFirebase];

}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler {
    NSLog(@"%@",userInfo);
}

- (void)tokenRefreshCallback:(NSNotification *)notification{
    NSString *refreshToken = [[FIRInstanceID instanceID] token];
    NSLog(@"Instance ID Token: %@",refreshToken);
    [self connectToFirebase];
}

- (void)connectToFirebase{
    [[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error){
        if (error != nil) {
            NSLog(@"Unable to connect to FCM %@",error);
        }else {
            NSLog(@"Connesso");
        }
        
    }];
}


@end
-----------------------------------

Si devono poi modificare le Capabilities del progetto attivando le Push Notification e Keyring Sharing


il problema principale e' quello di creare un certificato di autenticazione, aspetto che non e' presente sulla versione Android. La procedura e' spiegata nel dettaglio nel video e non e' esattamente banale

Un avvertimento: non e' possibile usare l'emulatore software di IOS, e' necessario utilizzare un dispositivo fisico







giovedì 1 dicembre 2016

Notifiche cloud con Firebase su Android

In questo post viene descritto come usare il cloud di Firebase per mandare notifiche push su dispositivi Android.

Per prima cosa ci si deve registrare, anche con account gratuito, sulla console di firebase e si crea un progetto



si crea quindi una nuova applicazione. E' possibile creare applicazione per Android ed IOS. In questo caso si sceglie Android


per creare l'applicazione e' richiesto il solo nome del pacchetto Android


a questo punto si clicca sul pulsante con i tre puntini sovrapposti e si visualizza la configurazione SDK



e si scarica il file google-services.json che dovra' essere copiato nella directory /app del proprio progetto

si crea quindi un progetto Android usando il nome del pacchetto gia' fornito nella configurazione di Firebase


build.gradle (Project)
-------------------------------------

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'        
        classpath 'com.google.gms:google-services:3.0.0'
        // NOTE: Do not place your application dependencies here; they belong        // in the individual module build.gradle files    }
}

allprojects {
    repositories {
        jcenter()
    }
}

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

build.gradle (Module: App)
-------------------------------------
apply plugin: 'com.android.application'
android {
    compileSdkVersion 23    
    buildToolsVersion "23.0.3"    
    defaultConfig {
        applicationId "com.lucainnocenti.notifica.notifica"        
        minSdkVersion 21        
        targetSdkVersion 23        
        versionCode 1        
        versionName "1.0"        
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }
    buildTypes {
        release {
            minifyEnabled false            
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }
    }
}

dependencies {
    compile 'com.google.firebase:firebase-messaging:10.0.0'    
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'    })
    compile 'com.android.support:appcompat-v7:23.4.0'    
   testCompile 'junit:junit:4.12'}

apply plugin: 'com.google.gms.google-services'
-------------------------------------



AndroidManifest.xml
-------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.lucainnocenti.notifica.notifica">

    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <service        android:name=".MyFirebaseMessagingService" android:exported="false">
        <inter-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </inter-filter>
    </service>

    <service        android:name=".MyFirebaseInstanceIdService" android:exported="false">
        <inter-filter>
            <action android:name="com.google.firebase.MESSAGING_ID_EVENT" />
        </inter-filter>
    </service>
</manifest>
-------------------------------------



MyFirebaseMessagingService.java
-------------------------------------
package com.lucainnocenti.notifica.notifica;

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceIdService;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

/** * Created by root on 29/11/16. */
public class MyFirebaseMessagingService extends FirebaseMessagingService{
    private static final String TAG="MyFMService";

    @Override    public void onMessageReceived(RemoteMessage remoteMessage)
    {
        Log.d(TAG,"ID :"+remoteMessage.getMessageId());
        Log.d(TAG,"Notification :" +remoteMessage.getNotification());
        Log.d(TAG,"Data : "+remoteMessage.getData());

    }
}
-------------------------------------

MyFirebaseInstanceIdService.java
-------------------------------------
package com.lucainnocenti.notifica.notifica;

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import com.google.firebase.messaging.FirebaseMessaging;

/** * Created by root on 29/11/16. */
public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
    private static final String TAG="MyFirebaseIIDService";
    private static final String FRIENDLY_ENGAGE_TOPIC = "friendly_engange";



    @Override    public void onTokenRefresh(){
    String token = FirebaseInstanceId.getInstance().getToken();
    Log.d(TAG,"Token " + token);
        FirebaseMessaging.getInstance().subscribeToTopic(FRIENDLY_ENGAGE_TOPIC);
    }

}
-------------------------------------

Una volta compilata ed installata l'applicazione si crea un messagggio dall'interfaccia web della Firebase Console dal menu Notification
Si possono creare diverse regole. La cosa piu' semplice e' mandare il messaggio a tutti gli utenti che hanno installato l'applicazione impostando il solo identificativo del pacchetto (altrimenti per creare dei messaggi personalizzati bisogna conoscere gli identificativi unici dei vari client)


Non e' possibile avere un QoS .. in pratica si sa se il messaggio e' stato inviato dal server ma non quanti sono stati consegnati regolarmente

Per inviare messaggi non e' strettamente necessaria l'interfaccia Web. Si puo' utilizzare anche il comando curl da riga di comando

Per prima cosa si clicca sull'icona dell'ingranaggio vicino al nome del progetto e si selezionano le impostazioni del progetto, si seleziona Cloud Messaging e si copia la Server Key (nel futuro si dovra' usare il token ovvero il codice sottostante)


e si lancia poi il seguente comando inserendo la
---------------------------------------
curl --insecure --header "Authorization: key=XXXXXXXXXXXX" --header "Content-Type:application/json" -d "{\"notification\":{\"title\":\"note-Title\",\"body\":\"note-Body\"}}" https://fcm.googleapis.com/fcm/send
---------------------------------------



Opencv camera calibration in cpp

Oltre che con uno script Python come visto qui la calibrazione della camera si puo' fare anche con il programma in CPP Questo il proce...