Product

Triggering Firebase Cloud Functions with Radar events

Radar abstracts away the challenges and cross-platform differences of location context and tracking, allowing you to add location context and tracking to your app with just a few lines of code.

Cloud Functions for Firebase lets you automatically run backend code in response to events triggered by Firebase features and HTTP requests.

Radar can send geofence and place events to any HTTP endpoint, including Firebase Cloud Functions. Firebase is therefore a great way to write serverless backend code triggered by Radar events.

https://s3.amazonaws.com/io.radar.blog/posts/triggering-firebase-cloud-functions-with-radar-events/firebase.png

To show how simple it is to use Radar + Firebase, we'll write a Firebase Cloud Function that sends a Firebase Cloud Messaging (FCM) push notification whenever a user visits a Starbucks. We simply need to:

  1. Integrate the Radar and Firebase SDKs into our iOS or Android app
  2. Configure Radar Places
  3. Add a Radar webhook
  4. Write and deploy a Firebase Cloud Function

The same principles apply to other use cases as well.

1. Integrate the Radar and Firebase SDKs

We can integrate the Radar SDK and Firebase SDK into an iOS or Android app with just a few lines of code.

To integrate the SDKs, we simply:

  • import and initialize the SDKs
  • set a Radar place data provider
  • request permissions
  • start Radar background tracking
  • store the user's FCM token in Radar metadata

On iOS, our code looks something like this:

import RadarSDK
import Firebase

// ...

@UIApplicationMain
class AppDelegate: UIApplicationDelegate, MessagingDelegate {

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()
    Messaging.messaging().delegate = self

    let publishableKey = Utils.getRadarPublishableKey()

    Radar.initialize(publishableKey: publishableKey)
    Radar.requestAlwaysAuthorization()
    Radar.setPlacesProvider(.facebook)
    Radar.startTracking()

    // ...

    return true
  }

  // ...

  func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
    let metadata = ["fcmToken": fcmToken]
    Radar.setMetadata(metadata)
  }

}

On Android, our code looks something like this:

import com.onradar.sdk.Radar;

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

// ...

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Radar.initialize(this);
    Radar.setPlacesProvider(RadarPlacesProvider.FACEBOOK);
    Radar.requestPermissions(this);
    Radar.startTracking();

    // ...
  }

}

public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {

  @Override
  public void onTokenRefresh() {
    String fcmToken = FirebaseInstanceId.getInstance().getToken();

    try {
      JSONObject metadata = new JSONObject();
      metadata.put("fcmToken", fcmToken);
      Radar.setMetadata(metadata);
    } catch (JSONException e) {
      // ...
    }
  }
}

2. Configure Radar Places

Radar has three context types: Geofences, Insights (home, work, and traveling detection), and Places (place, chain, and category detection).

In this example, we'll enable Places and add Starbucks to the list of chains that we want to monitor:

https://s3.amazonaws.com/io.radar.blog/posts/triggering-firebase-cloud-functions-with-radar-events/settings.png

Now Radar will generate a place entry event whenever a user visits a Starbucks:

https://s3.amazonaws.com/io.radar.blog/posts/triggering-firebase-cloud-functions-with-radar-events/event.png

3. Add a Radar webhook

A Firebase Cloud Function can be invoked over HTTPS. Assuming we deploy our function in us-central1, assuming our project ID is foo, and assuming we name our function radar, our URL will be: https://us-central1-foo.cloudfunctions.net/radar

If we add a Radar webhook, Radar will send a POST request containing event data to this URL whenever an event is generated. The request body will look something like this:

{
  "event": {
    "_id": "56db1f4613012711002229f6",
    "createdAt": "2018-06-20T13:44:10.535Z",
    "live": true,
    "type": "user.entered_place",
    "location": {
      "type": "Point",
      "coordinates": [-87.648859, 41.910909],
    },
    "locationAccuracy": 5,
    "user": {
      "_id": "56db1f4613012711002229f4",
      "metadata": {
        "fcmToken": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
      }
    },
    "place": {
      "_id": "5a7fa9eedd752bf10994bb37",
      "facebookId": "561059110600455",
      "name": "Starbucks",
      "chain": {
        "name": "Starbucks",
        "slug": "starbucks"
      },
      "location": {
        "type": "Point",
        "coordinates": [
          -87.649067,
          41.910820
        ]
      },
      "categories": [
        "food-beverage",
        "cafe",
        "coffee-shop"
      ]
    },
    "confidence": 1
  }
}

4. Write a Firebase Cloud Function

Now we're ready to write and deploy our Firebase Cloud Function. In the function, we simply need to:

  • check the event type
  • check the chain ID
  • trigger a push notification with the user's FCM token
  • send a 200 OK response

Our code will look something like this:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

exports.radar = functions.https.onRequest((req, res) => {
  const type = req.body.event.type;
  if (type === 'user.entered_place') {
    const chain = req.body.event.place.chain;
    if (chain && chain.slug === 'starbucks') {
      const metadata = req.body.event.user.metadata;
      if (metadata && metadata.fcmToken) {
        const message = {
          notification: {
            title: 'At Starbucks? ☕️',
            body: 'Redeem your in-store offer now!'
          },
          token: fcmToken
        };
        admin.messaging().send(message);
      }
    }
  }
  res.sendStatus(200);
});

After we deploy our function, we're done! When a user visits a Starbucks, Radar will generate a place entry event and invoke our function:

https://s3.amazonaws.com/io.radar.blog/posts/triggering-firebase-cloud-functions-with-radar-events/notification.png


If you're a Firebase user and you want to integrate Radar, contact us! We'd love to help you get started.