title: Firebase Cloud Function - Triggering Expo SDK to Push Notifications to Users
body: <p>I am working on an app based of Expo - I decided to use firebase as a backend but had come up to a blocker, I need to send push notifications to the users in the app - but Expo doesn't work with Firebase Cloud Messaging (FCM) unless I eject the Expo project and work independently with Android and ios.</p>
  
  <p>To overcome this I decided to store the Expo Notification Tokens in firebase and then write a firebase cloud function in firebase to get all these tokens from the database and trigger a sendPushNotificationAsync() using the expo-server-sdk. </p>
  
  <p>I understand that to do this approach my version of firebase cannot be on the Spark plan - and it isn't. </p>
  
  <p>I decided to implement the solution in TypeScript so I can conform to ES6/ES7 coding standards. </p>
  
  <p>The approach is - I trigger a get request to my firebase function url and this triggers the function to execute. With the code below - when I do a get request against the provided google function URL I get an error: </p>
  
  <blockquote>
    <p>@firebase/database: FIREBASE WARNING: Exception was thrown by user 
        callback. TypeError: expo.isExpoPushToken is not a function
        at admin.database.ref.once (/user_code/lib/index.js:24:18)
        at onceCallback (/user_code/node_modules/firebase-</p>
  </blockquote>
  
  <p>Is there something I am doing incorrectly it doesn't seem like it is able to initialise and use functions from the Expo import, although I have included this in the package.json to be installed, imported and used. </p>
  
  <p>index.ts - generated by firebase</p>
  
  <pre><code>import * as functions from 'firebase-functions';
  import * as admin from 'firebase-admin';
  import * as Expo from 'expo-server-sdk';
  
  admin.initializeApp();
  // Create a new Expo SDK client
  let expo = new Expo();
  
  exports.pushNotifications = functions.https.onRequest((req,res) =&gt; {
    if(req.method !== 'GET'){
      return res.status(403).send('Forbidden!')
    }
  
    let allTokens = [];
    let messages = [];
  
    admin.database().ref('/all_user_push_tokens/').once('value', (snapshot) =&gt; {
      if(expo.isExpoPushToken(snapshot.val())){
        allTokens.push(snapshot.val())
      } else {
        console.log(snapshot.val())
      }
    })
    .then(() =&gt; {
      for (var token in allTokens){
        messages.push({
          to: token,
          sound: 'default',
          title: 'NXET',
          body: ' NEW ACTIVITIES ADDED!'
        })
      }
    })
    .then(() =&gt; {
      let chunks = expo.chunkPushNotifications(messages)
  
      async (chunks) =&gt; {
        for (let chunk of chunks) {
          try {
            await expo.sendPushNotificationsAsync(chunk);
          } catch (error){
            console.error(error);
          }
        }
      }
  
      return res.status(200).send('SUCCESS - NOTIFICATIONS SENT!!')
  
    })
    .catch(() =&gt; {
      return res.status(403).send('Forbidden!')
    });
  
    return res.status(200).send('Function Executing')
  
  })
  </code></pre>
  
  <p>package.json</p>
  
  <pre><code>{
  
  "name": "functions",
    "scripts": {
      "build": "tsc",
      "serve": "npm run build &amp;&amp; firebase serve --only functions",
      "shell": "npm run build &amp;&amp; firebase functions:shell",
      "start": "npm run shell",
      "deploy": "firebase deploy --only functions",
      "logs": "firebase functions:log"
    },
    "main": "lib/index.js",
    "dependencies": {
      "expo-server-sdk": "^2.3.3",
      "firebase-admin": "~5.12.0",
      "firebase-functions": "^1.0.1"
    },
    "devDependencies": {
      "typescript": "^2.5.3"
    },
    "private": true
  }
  </code></pre>
  
  <p>Any help would be much appreciated.</p>