Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

How to enable the Firebase server on IM App:

Go to

...

AdminCP > Apps > Installed > Instant Messaging > Settings and select "Firebase" at setting Select chat server

...

Then, configure the required Firebase Config Object

...

 setting. We will guide you to get the value when adding Firebase project which will be instructed below.

Also, you can configure Algolia App ID (Optional) and Algolia API Key (Optional) to support search messages. The instructions will be given later.

Setup Google Firebase App:

1. Add Firebase project

Go to Firebase console

Select Add Project if you don't have one

Image Modified

Go to App Dashboard, select Project Overview > Project settings 

Image Modified

In Your apps section click on icon </> to Add Firebase to web app

Image Modified

Add App nickname, then click Register App, then click Continue to console to back to Project Settings page
Image Modified

In Your Apps section, chose the app you just created, then click on Config 

...

option of Firebase SDK snippet. Copy all script code  and paste to Firebase Config Object

...

 setting in AdminCP > Apps > Installed > Instant Messaging > Settings area.
Image Modified

2. Enable Firebase Database

Back to Firebase App Dashboard, select Develop > Database.

...

 Then, right-click on Create Database.

...

Select mode and click Enable
Image Modified

After

...

enabling, you will redirect to database page.

...

 In that page, select tab Indexes and add 2 Composite indexes to Database by click on Create index manually. 

...

Then, configure fields as 2 screenshots below:
 Image Modified

Image Added

Indexes enable:
Image Modified

...

Go to Develop > Authentication, enable Sign-in method for Email/

...

Password provider in your project 

...

to allow users access to the database,

...

as the following screenshot:
Image Modified

Then, go to Database Rules tab and

...

add the following database rules

...

:

Code Block
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: 
      if request.auth.uid != null && request.auth.token.email.matches('^user_([0-9]+)@.*');
    }
  }
}

Rules table will be as the below image:

Image Modified

Now, you can start to use IM App with Firebase.

...

Note: Without Algolia configure on IM App, users can only search for messages with prefix and case sensitive.

Go to Algolia App Manage, sign up if you don't have an account

Note: Algolia is pay to use, so you should check their pricing at Algolia Pricing

Go to your

...

 App Dashboard
Image Modified

Select Indices, create new Index with name im_chat

Image Modified

After Create Index, select menu API keys on left

  • Copy Application ID and paste to setting Algolia App ID on IM App
  • Copy Admin API Key and paste to setting Admin API Key on IM App

Image Modified

Now, users can search full-text messages with IM App and Firebase

Setup Cloud Functions support push notification on Mobile App

Refer tutorial from https://firebase.google.com/docs/functions/get-started

1. Set up Node.js and the Firebase CLI

 

You'll need a Node.js environment to write functions, and you'll need the Firebase CLI (which also requires Node.js and npm) to deploy functions to the Cloud Functions runtime. From among the supported Node.js versions available for Cloud Functions, we strongly recommend Node.js 8 for getting started. For installing Node.js and npm, Node Version Manager is recommended.

 

Once you have Node.js and npm installed, install the Firebase CLI via npm:

Code Block
npm install -g firebase-tools

2. Initialize Firebase SDK for Cloud Functions

...

Structure of your project

Code Block
myproject
 +- .firebaserc    # Hidden file that helps you quickly switch between
 |                 # projects with `firebase use`
 |
 +- firebase.json  # Describes properties for your project
 |
 +- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # main source file for your Cloud Functions code
      |
      +- node_modules/ # directory where your dependencies (declared in
                       # package.json) are installed

Edit package.json file, add new module request to dependencies object

Code Block
{
  "name": "functions",
  ....
  "engines": {
    "node": "8"
  },
  "dependencies": {
    .....
    "request": "^2.88.0"
  },
  ....
}

Then run cd functions/ && npm install (from project folder) to update project modules.

...

Code Block
const functions = require('firebase-functions')
const admin = require('firebase-admin')
const request = require('request')

admin.initializeApp()

const firestore = admin.firestore()

exports.sendPushNotification = functions.firestore.document(
  'rooms/{roomId}/messages/{messageId}').onCreate(event => {
  const writeData = event.data()
  const sender = writeData.sender
  const recipient = writeData.receiver
  if (!writeData.sender_id || !writeData.server_key) {
    return false
  }
  const notifyTo = {
    recipient: recipient,
    sender_id: writeData.sender_id,
    server_key: writeData.server_key
  }
  let payload = {}
  firestore.doc('users/' + sender).get().then(doc => {
    const senderData = doc.data()
    payload = {
      notification: {
        title: senderData.name,
        body: writeData.text ? writeData.text : '[FILE]',
        sound: 'default'
      },
      data: {
        resource_link: 'chat/' + senderData.id,
        web_link: 'chat/' + senderData.id
      }
    }
    return getTokenToSend(payload, notifyTo)
  }).catch(e => console.warn(e))
  return true
})

function getTokenToSend (payload, notifyTo) {
  const recipientId = Buffer.from(notifyTo.recipient, 'base64').
    toString('ascii')
  const notificationKeyName = 'user-' + recipientId
  return getNotificationKey({
    senderId: notifyTo.sender_id,
    serverKey: notifyTo.server_key
  }, notificationKeyName).
    then(notificationKey => admin.messaging().
      sendToDeviceGroup(notificationKey, payload))
}

function getNotificationKey (options, notificationTokenName) {
  return new Promise((resolve, reject) => {
    request({
      url: 'https://fcm.googleapis.com/fcm/notification',
      method: 'GET',
      json: true,
      headers: {
        Authorization: 'key=' + options.serverKey,
        project_id: options.senderId,
        'Content-Type': 'application/json'
      },
      qs: { notification_key_name: notificationTokenName }
    }, (error, httpResponse, body) => {
      if (!error && body.notification_key) {
        resolve(body.notification_key)
      } else {
        reject(error || body)
      }
    })
  })
}

...