Support iBeacons In Your Ionic Framework Mobile App

I recently picked up some Estimote iBeacons to play around with and figured I’d try to get them working in an Ionic Framework Android and iOS application.

If you’re unfamiliar with iBeacons, they are small bluetooth proximity devices.  There are many different manufacturers, but Estimote appears to have the best advertised battery life and durability.  iBeacons generally broadcast a signal every 100ms to 1000ms depending on the configuration or brand.  The broadcast signal contains a UUID and two numeric identifiers which are a major and minor version.

Before I get into the code I’ll share a few possible use cases for iBeacons:

  1. Triggering some literature or audio when your device detects that you’re near a particular iBeacon in a museum.  Put one near The Statue of David in Italy and bam, you could have information about it when you approach it.
  2. Tracking foot traffic in your store.  Maybe you have a large store like Walmart with iBeacons in every department.  You can see which department gets the most traffic.
  3. Calculating how long time-wise a queue / line is for a particular ride at an amusement park based on device to beacon discovery.

There are endless other useful scenarios.

Alright so you know a bit more about iBeacons, now it is time to get into the code.  Assuming you already have Ionic configured on your machine, from the Terminal or Command Prompt run the following commands:

If you are not using a Mac, do not try to add and build for the iOS platform.  Only Android will work on Linux and Windows machines.

The plugin we’re going to use for iBeacons is cordova-plugin-ibeacan by Peter Metz.  At the time of writing this tutorial, I am using the latest version which is commit 50315dbc.  If you want to be adventurous and see if a newer version works, that is up to you.

With IonicBeacon as the working directory of your Terminal or Command Prompt, run the following to install the plugin:

We are almost ready to start coding.  The iBeacon plugin by Peter Metz is plain JavaScript and doesn’t work the best with Ionic out of the box.  Instead, we’re going to use the AngularJS wrapper I wrote for this plugin.  The wrapper ng-cordova-beacon can be found on my GitHub page.  Download ng-cordova-beacon.min.js from the dist directory and drop it in your project’s www/js directory.

Next up, open your project’s www/index.html file and include the following JavaScript file above the app.js line:

With the AngularJS wrapper included, open your project’s www/js/app.js file and include the following code:

Let’s break down what is happening here.

First we need to inject ng-cordova-beacon into the AngularJS module.  With that added we can proceed to using it in our controller.

Since the plugin uses native device code we need to wrap any calls to it in an $ionicPlatform.ready before we try to use it.  For iOS only we are requesting permission to use location services.  On Android this request will be ignored because it isn’t necessary.

In the $rootScope.$on call we are listening for ranging hits.  Basically we are checking if the iBeacon is in range and how far it is.  If the broadcast is found, add the found beacon to an object that we can use on the front-end view.

Finally we are starting to range for a region of beacons.  You can call this as many times as you want for different sets, but I’m just ranging for one set of beacons.  The one set being the following:

I chose to use estimote as a human readable identifier for the UUID that follows.  You can optionally include a major and minor version, but by leaving them out you are using a wildcard.  You can have multiple majors and minors per UUID so by leaving them off, you may get many results.

The final thing to worry about is how this app is going to look.  Going back to the project’s www/index.html file, add the following code between the <ion-content> tags:

I’m using a class Ionic doesn’t include called truncate which we need to add.  Open your project’s www/css/style.css and add the following:

We’re using this so our very long UUID values don’t float off the screen.  Instead they will be gracefully clipped if they are too long.

Ionic iBeacon iOS iBeacon Ionic Android

Above is what the application should look like when it has detected iBeacons.

Conclusion

You can do a lot of cool things with iBeacons and they aren’t difficult to use with Ionic Framework.  You can pick up a developer kit from Estimote, which includes several beacons compatible with both Android and iOS.

A video version of this article can be seen below.

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

  • John

    Awesome stuff, something that I had planned looking into. Thanks Nic

    • No problem!

      • need info

        Following the steps, my IonicBeacon application displayes text {{value.uuid}} major:{{value.major}} etc.. What could be wrong?

        • Can’t tell you without seeing your logs

          • need info

            got the issues fixed..however this plugin works only if the UUID is not null/valid. However, in my case, the beacon I have doesn’t have a UUID(is null) and I need to get the mac ID.( UUID is not mandatory for android?) and scan,read the raw ad records of beacon.Please advise.

          • Doesn’t sound like your beacons are following the correct spec. All iBeacon have a unique identifier, and a major and minor value. There are many other types of proximity beacons, iBeacon being what this plugin works with.

            If you think your beacons are truly following the iBeacon spec you should contact the plugin developer. The wrapper I wrote is just a wrapper to the actual plugin.

            Best,

          • need info

            Thanks for clarification. In fact what I am looking for in my ionic app is: scan all BLE devices near by and read their advertising records.looking for pointers to achieve this?

          • The iBeacon plugin will not accomplish this because not all BLE devices are iBeacons. You’ll have to find a different BLE plugin to accomplish this, and my guess it will be nothing like the iBeacon guide I wrote.

            Best,

  • teddy

    Amazing work! Thank you so much NIC

    • No problem. Thanks for the compliment!

  • mr_mlund

    What if the app is not running when it nears the beacon. Any way to notify the user, and/or push content?

  • kumar_garapati

    Awesome. Thanks for posting this. I am planning to get some beacons and try out .

    • Awesome! Let me know how it goes 🙂

  • Gelder De la ossa

    I think the same than yours…..It’s something that I have waiting and today I realize that you did! thanks!!!!! I’m starting a Ibeacon project. Cheers from Colombia.

    • No problem. Glad I could help 🙂

  • Koen Mulder

    Nice, it really helps me develop my application. Do you also have some information about the implementation of a service (AngularJS) with iBeacons and functions?

    • Do you have an example of what you’re trying to accomplish?

  • Harsh Vardhan

    Hi Nic,

    How can I stop the beacon from scanning anymore. I tried this but doesn’t work

    $cordovaBeacon.stopRangingBeaconsInRegion($cordovaBeacon.createBeaconRegion(“estimote”, “b9407f30-f5f8-466e-aff9-25556b57fe6d”));

    • It is my understanding that you need to specify which beacon you want to stop monitoring. So I believe you need to pass in a minor and major rather than leaving it as a wildcard.

      Here is the official documentation for stopping a beacon:

      https://github.com/petermetz/cordova-plugin-ibeacon#stop-ranging-a-single-ibeacon

      Regards,

      • Harsh Vardhan

        Thanks man that solved my issue 🙂

        To anyone else who is working on this, that’s how you can nicely start and stop a beacon
        var beaconRegion = $cordovaBeacon.createBeaconRegion(“estimote”, “ebefd083-70a2-47c8-9837-e7b5634df524”, “1”, “1”);

        $cordovaBeacon.startRangingBeaconsInRegion(beaconRegion);
        $cordovaBeacon.stopRangingBeaconsInRegion(beaconRegion);

  • Luís Cunha

    Hi Nic,

    This example is not responding to when a beacon becomes out of range or is turned off, as in, it’s still displaying it in the list.
    How do I make it list only the beacons that are found?

    • In this example I did that on purpose. I configured my beacons to broadcast on much slower intervals to preserve battery. Because of this, the application code searches for the beacons much faster than the beacons have a chance to broadcast, making their status unknown more frequently. Whenever the application code says the beacon status is unknown, it means it could not find the beacon, either because it is out of range or something else.

      You just need to remove the beacon from the list if the status is unknown.

      Regards,

      • Luís Cunha

        Thank you for your reply. Does the plugin or the wrapper you wrote provide a way of detecting when a beacon is no longer present or would I have to do this on my own, and if so, how would be a good way to do it?

        • My wrapper is only a wrapper. You probably want to take a look at the plugin documentation as far as features go:

          https://github.com/petermetz/cordova-plugin-ibeacon

          When a beacon is unknown status, it may no longer be present. There are other ways if you look at the docs.

          Regards,

          • Luís Cunha

            My specific case involves making an http request to a server whenever a beacon is found to find out informations about the location the beacon represents. The issues I’m facing are controlling scan intervals from the app side and if a beacon is no longer being detected, to remove it from the list.
            From what I could read in the plugin documentation I can only stop scanning for 1 specific beacon at a time and now pause the scanning itself and I wasn’t able to find a way to time out beacons that are unknown for too long.
            This could be achieved without the plugin, but would require some hacks and workarounds, and I’d like to avoid that.
            How would be a good way to control scan frequency and beacon presence?

          • You probably want to read this by Estimote:

            https://community.estimote.com/hc/en-us/articles/203356607-What-are-region-Monitoring-and-Ranging-

            You want to use monitoring where as in my example I used ranging. The article above will explain the differences.

            Best,

          • Luís Cunha

            Actually I do want ranging, otherwise I’d have to have a different region for each beacon to know which beacons I am no longer seeing. I also require distance information. From the article you provided I was able to find out that, on iOS, it is indeed impossible to control scan frequency, which is a shame and will require a manual workaround. Same goes for the beacon presence it seems.

          • Yea there are limitations unfortunately.

            Here is what I would do. When you get ranging information about a beacon I would also store the current timestamp if the status is unknown. Then in your code, do a check either by polling or every time a change happens, to see if X amount of time has passed from that timestamp for the unknown beacon. This way you can say something like “if beacon is unknown for 3000ms, then we are truly out of range so remove it”

            Shouldn’t take more than a few lines of code to do.

            Does that make sense?

          • Luís Cunha

            That is similar to what I did, the major problem is the battery drain the constant ranging in the background does. What I was thinking of doing in that regard was using a $interval to stop and start the ranging process altogether, but I suspect the service binding won’t allow it, plus I’d have to do it for each separate beacon.
            You mention listening for when a change happens, is an event triggered when a change in ranging occurs?

          • I meant in here:

            $rootScope.$on(“$cordovaBeacon:didRangeBeaconsInRegion”, function(event, pluginResult) {

            It is not fool-proof, but it is an option. Would it make sense to do this?:

            Start monitoring for beacons. When beacon is found, start ranging for the beacon that is found. When monitoring says the beacon is out of range, stop ranging for the beacon.

            Might be better on battery that way?

            Being how basic iBeacons are, I think it is really up to the developer to model it to what best works for them.

          • Luís Cunha

            I’m currently doing all my logic in the didRangeBeaconsInRegion function. How do I stop ranging a specific beacon without stopping the ranging for that region? Let’s say that I have a beacon inside each store on a street and whenever a new store is in range I do an &http request to a server to get more info on the store and then display a notification for that store to the user.

            I just have one region since I’m not using any region related logic, just single beacon logic, and all this should still happen in the background. I can control at which rate I do all my logic, but by enforcing time intervals since the last relevant change happened, not the hardware processing itself.

            Would it be possible/worth it to stop ranging for the one region and resuming it 5-6s later?

            Also, I didn’t fully understand your suggestion, as in, is it possible, by monitoring and not ranging, to detect when new beacons are found? I was under the impression that monitoring could only happen on entering/leaving regions, is this not so?

          • Now you have me questioning what I know about iBeacons 😛

            Beacons can share the same UUID, but they will all have different minor and major values. You can start ranging for wildcard minor and major values and then stop a specific minor and major.

            You are correct about monitoring. But what I was suggesting is don’t use proximity services unless monitoring says you are in a region because you were worried about battery life.

            Don’t take this the wrong way, but I think you should post a question in the Estimote forums (or similar). I can help with the coding, but when it comes to iBeacon concepts you might be leaving my area of knowledge 🙂

            Best,

          • Luís Cunha

            I am in fact scanning for wild card majors and minors. I also think that the ranging stuff should only start after a region has been entered, should I just stopRangingBeaconsInRegion(beaconRegion) whenever not inside any region?

            The documentation only mentions operations on individual beacons, but is it possible to stop ranging the region if I’m wild-carding the beacons?

            If that’s possible, it’d be an acceptable solution, and I would only initiate didRangeBeaconsInRegion when inside a region.

          • You can only stop a single specific beacon. You can start on many beacons (wildcard), but you can only stop specific. I’m not sure why that would be an issue for you though.

          • Luís Cunha

            The only thing that would really help my case with the battery drain, and the app store acceptance as well, would be to control when ranging in the background is on/off as a whole, just turning one off. But in any case, I got it all working, thank you for your help =)

          • No problem! Glad I could help 🙂

          • Luís Cunha

            Just wanted to mention that wildcard beacon ranging interruption does work 100% on android and not quite on iOS, but doing something like

            rangedInRegion(beaconResult){
            for(beacon in beaconResult){
            auxRegion =new region(“same UUID as the global region”, beacon.major, beacon.minor);
            stopRanging(auxRegion);
            $timeout(function() {
            startRanging();
            },3000);
            }}

            does work and controls the ranging intervals, and greatly reduced the battery consumption.

          • Thanks for reporting back! I’m sure this information will help others 🙂

  • erikvan

    Love the tutorial. Trying to figure out how to work with monitoring the region as opposed to ranging the region with your wrapper.

    Not sure why the

    var region = $cordovaBeacon.createBeaconRegion(“shopping-centre”, “b9407f30-f5f8-466e-aff9-25556b57fe6d”);

    console.log(pluginResult);
    $scope.result = JSON.stringify(pluginResult);
    $scope.$apply();
    });

    • erikvan

      Answering my own question here.. turns out you need to have the right app permissions for monitoring to work.

      https://community.estimote.com/hc/en-us/articles/203356607-What-are-region-Monitoring-and-Ranging-

      so need to have:
      $cordovaBeacon.requestAlwaysAuthorization();

      for the state to be triggered.

      • Yep that would make sense 🙂

      • Ramadhevi Rk

        I m having the same problem right now!! Could you explain the fix? Where did you add the $cordovaBeacon.requestAlwaysAuthorization().. An example would be perfect 🙂 Thank Ya

        • erikvan

          Hi Ramadhevi,

          It’s really up to you where you put it. In the article’s example it would be put in after the:

          $ionicPlatform.ready

          Hope that helps

          • Ramadhevi Rk

            Hi erikvan,
            Thanks for replying back! It would be a great help if you post a working example for monitoring. Thanks again

  • Pitu

    For the past months I’ve been discovering the cordova / ionic universe and everytime I had a doubt or problem about a funcionality I wanted to add I find out you already made a post about it. Thank you SO very much for keeping this site up and running, it truly is an inspiration.

    • Thank you for the compliment! I’m glad you continue to find my blog useful 🙂

  • Mch505

    Hi, i’m new with ionicframework and hybrid apps in general i’m using your example but not with estimote’s ibeacons, i’m using just a bluethoot 4 device and broadcasting the signal, with beacon scanner app works perfect, i changed the uuid with the uuid of my device, there’s any form to wildcard the uuid?, when i try using IonicView to see the app in my device, the app never find anything and never enters to $rootScope.$on(“$cordovaBeacon:didRangeBeaconsInRegion”, function(event, pluginResult), i hope you can help me with my problem, your posts are always the better please keep it going!

    • Rule #1, never use ionic view, ionic serve, ionic live-reload, or phonegap build when working with native plugins. These are all alpha / beta services and are known to have a ton of problems.

      If it still fails beyond that, get me your logs.

      Best,

      • Mch505

        Ok, thanks i will do that!

      • Mch505

        I build the app with the android sdk and didn’t work, were can i get the logs (sorry a noob here), i create an array and push a message when someting happens, like the controller init, when the platform is ready, the code is this https://gist.github.com/cheves505/ac3fc679f98d356fb490

        But it seems it never enters in the $rootScope.$on(“$cordovaBeacon:didRangeBeaconsInRegion”, function(event, pluginResult)

        Where can i get the logs of the app to show you my logs?

  • Loco Van Coco

    Hi Nic, do you also have a example on using this code with monitoring instead of ranging. Thanks

    • I usually only do one example and let everyone leave the rest to their imagination. What have you tried already?

      • Loco Van Coco

        this is what i want to achieve:

        Lookup for beacons available beacons without defining a uuid or identifier. (is this monitoring?)
        Connect to the nearest beacon and start ranging.

        this is what i’ve tried so far:

        $cordovaBeacon.startMonitoringForRegion($cordovaBeacon.createBeaconRegion(“radius”, “2f234454-cf6d-4a0f-adf2-f4911ba9ffa6”));

        $rootScope.$on(“$cordovaBeacon:didStartMonitoringForRegion”, function (event, pluginResult) {
        console.log(‘my_log:’ + JSON.stringify(pluginResult));
        });

        My logfile:

        2015-10-18 07:50:31.883 example[261:20913] Resetting plugins due to page load.

        2015-10-18 07:50:32.747 example[261:20913] Finished load of: http://192.168.1.12:8100/#/app/beacon

        2015-10-18 07:50:32.762 example[261:21068] [DOM] registerDelegateCallbackId()

        2015-10-18 07:50:32.762 example[261:21068] Registering delegate callback ID: LocationManager894243164

        2015-10-18 07:50:32.764 example[261:21188] [DOM] _onDelegateCallback() null

        2015-10-18 07:50:32.828 example[261:21273] didStartMonitoringForRegion: CLBeaconRegion (identifier:’radius’, uuid: 3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6, major:(null), minor:(null))

        2015-10-18 07:50:32.829 example[261:21273] Converted locationManager:didStartMonitoringForRegion: into didStartMonitoringForRegion

        2015-10-18 07:50:32.832 example[261:20913] my_log:{“eventType”:”didStartMonitoringForRegion”,”region”:{“uuid”:”3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6″,”identifier”:”radius”,”typeName”:”BeaconRegion”}}

        2015-10-18 07:50:32.832 example[261:21068] [DOM] _onDelegateCallback() {“eventType”:”didStartMonitoringForRegion”,”region”:{“uuid”:”3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6″,”identifier”:”radius”,”typeName”:”BeaconRegion”}}

        2015-10-18 07:50:32.832 example[261:21068] [DOM] _mapDelegateCallback() found eventType didStartMonitoringForRegion

        0 432830 log my_log:{“eventType”:”didStartMonitoringForRegion”,”region”:{“uuid”:”3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6″,”identifier”:”radius”,”typeName”:”BeaconRegion”}}

        2015-10-18 07:50:41.591 example[261:21273] didDetermineState: CLRegionStateOutside for region: CLBeaconRegion (identifier:’radius’, uuid: 3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6, major:(null), minor:(null))

        2015-10-18 07:50:41.592 example[261:21273] Converted locationManager:didDetermineState:forRegion: into didDetermineStateForRegion

        2015-10-18 07:50:41.599 example[261:21273] [DOM] _onDelegateCallback() {“eventType”:”didDetermineStateForRegion”,”state”:”CLRegionStateOutside”,”region”:{“uuid”:”3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6″,”identifier”:”radius”,”typeName”:”BeaconRegion”}}

        2015-10-18 07:50:41.600 example[261:21273] [DOM] _mapDelegateCallback() found eventType didDetermineStateForRegion

        • It isn’t possible to monitor or range for beacons without at least their uuid. Usually you’d store all the active beacons for your business in a database so that way you can monitor for those beacons.

          Monitoring tells you if you enter or exit a beacon region. Regioning tells you how far you are from a particular beacon.

          Best,

  • Shalini Pachineela

    Hi Nic. Great post and it was really helpful. I got an iBeacon which triggers notifications on my phone (ionic app) when the beacon is in range.
    Is it possible to trigger the notification even when the app is not running? It works fine when the app is in the foreground or background.

    • You mean local notifications?

      Apache Cordova background processes won’t work in Android Lollipop or Marshmallow. You might want to plan accordingly.

  • Ramadhevi Rk

    I really loved this blog of you.. The app is displaying the beacons in range along with their UUID, Minor, MajorIDs, Proximity values, RSSI, accuracy & so. It shows the proximity value as ProximityNear always. What are the other values the ProximityNear might take? I want to display distance in meters. How to accomplish that?

    • Ramadhevi Rk

      figured out myself 🙂

      Accuracy field is the distance between the device and the beacons

  • Ramadhevi Rk

    hi @nicraboy:disqus
    the code you have provided here is just ranging for beacons at once.. it s not live updating when the devices moves out of beacons..

    • No, the code I provided will range the beacons and display the current proximity as you move. It is not a one shot deal.

      • Ramadhevi Rk

        ok! I think $scope.$apply() have to be in the event “$cordovaBeacon:didRangeBeaconsInRegion” callback

        function. So that it updates actively..

        Your blog is really helpful.. Keep going!

        BTW, any way to measure temperature of the room with beacons?

        • iBeacons are for determining proximity, not temperature.

  • Ramadhevi Rk

    hi Nic Raboy

    You have stated

    Finally we are starting to range for a region of beacons. You can
    call this as many times as you want for different sets, but I’m just
    ranging for one set of beacons. The one set being the following:

    are you sure that we can range for different set of beacons by replacing the identifier and UUID appropriately using the following line of code?

    $cordovaBeacon.startRangingBeaconsInRegion($cordovaBeacon.createBeaconRegion(“estimote”, “b9407f30-f5f8-466e-aff9-25556b57fe6d”));

    It appears that when I did range for 3 different sets of beacons, it ranged only the last set of beacons.

    $cordovaBeacon.startRangingBeaconsInRegion($cordovaBeacon.createBeaconRegion(“estimote”, “blah-blah”, “blah-blah”, “blah-blah”));

    $cordovaBeacon.startRangingBeaconsInRegion($cordovaBeacon.createBeaconRegion(“estimote”, “blah-blah”, “blah-blah”, “blah-blah”));

    $cordovaBeacon.startRangingBeaconsInRegion($cordovaBeacon.createBeaconRegion(“estimote”, “blah-blah”, “blah-blah”,”blah-blah”));

    And also when I create a region using $cordovaBeacon.createBeaconRegion(“estimote”, “blah-blah”, “blah-blah”,”blah-blah”), the pluginResult.beacons not having the identifier field.. So thought identifier don’t make sense to have. So I used the same identifier everywhere.

    • I own three different brands of beacons. I have five beacons in total. When I try to range all 3 brands (3 different uuid values), it works without issue. All Estimote beacons will have the same uuid, so trying to range multiple times will likely cause errors.

      Can you confirm that every time you start ranging something new, it is a different uuid?

      Regards,

      • Ramadhevi Rk

        thanks for getting back.. I m ranging 5 beacons who have same UUID and different major and minor ID. So you mean that s the problem?

        • If you have 5 beacons with the same UUID then you have two options:

          Start ranging one time with only the UUID and leave the major and minor values off so they become wildcards
          Start ranging five times with the same UUID, but make sure to include unique major and minor values every time

          I’ve tried both scenarios and it works perfectly for me.

          Regards,

          • RAMDdFLEET

            Did you put ranging for different sets of beacons in loop?
            $scope.beacons=[{identifier: “beacons1″, uuid:”XXXXXXXXXXXXXXXXXXXXXXX”},{identifier: “beacon2”, uuid: “YYYYYYYYYYYYYYYYYYYY”}]
            for(var i in $scope.beacons){
            $cordovaBeacon.startRangingBeaconsInRegion($cordovaBeacon.createBeaconRegion($scope.beacons[i].identifier, $scope.beacons[i].uuid));
            }

          • No, but it shouldn’t matter. Maybe for whatever reason you’re having issues with wildcard major and minor values. Try adding them for all your beacons?

  • Luís Cunha

    Great tutorial, makes beacon handling much more manageable.

    • That is weird. I looked at the change history and nothing has changed. I also validated that my plugin waits until the device is ready to start using the Apache Cordova plugins.

      What version of iOS and is this device or simulator?

      • Luís Cunha

        iPad 2 running iOS 9.1 with cordova 5.3.3, cordova-ios 3.9.2 and ionic 1.1.1 , and I have the controller code wrapped in

        $ionicPlatform.ready(function () { });

        I also have the page structure inside an ion-side-menu, although I doubt that would break anything.

        • Very weird. My iOS devices are using 9.1 and they work fine with this code.

          Remove the plugin and add it again?

          Best,

          • Luís Cunha

            I was indeed some problem with the plugin installation. It’s all working as expected now.

          • Awesome!

            I haven’t figured out the reason yet, but every once in a while Apache Cordova plugins get a little nutty and need to be installed again.

            Best,

  • Nur

    hi @nicraboy:disqus , do you know where I can find codes such that when the mobile app detects the beacon, an image will appear? I tried to search online but unable to find so. I am using android platform and using cordova to create the application. Thank you for taking your time reading and replying my message.

    • Posting multiple comments to get my attention is not a good way to get my help. Just keep that in mind for the future.

      Beacons offer nothing beyond a unique id, major code, and minor code. You’ll have to keep a database of beacons and their matching images so when a beacon is detected you can use the beacon information to query the database for the particular image.

      You should note that in Android 5.0+, background processes do not work in Apache Cordova apps. It has to do with the permission system Google put into place. On iOS, you can watch for beacons in the background and trigger a local notification or something when detected.

      Regards,

  • Nur

    @nicraboy:disqus

  • Nur

    @nicraboy:disqus .

  • Hi Nic, first congratulations for your blog you have very interesting stuff here 🙂

    I’ve tried this tutorial but it doesn’t detect anything using two different phones. I wonder if the plugin you are using is out-of-date (last commit is from May ’15) or something because using a different plugin (last commit from yesterday): https://github.com/evothings/cordova-plugin-ibeacon I can detect my iBeacons.

    Is there any way to try this from my laptop??? you know “ionic serve” and hook my bluetooth peripheral

    • Still works for me. The beacon spec hasn’t changed which is why the plugin is still valid. Do you get any errors?

      Don’t use ionic serve. That shouldn’t be used in any application that uses a plugin. This is something you’ll have to test from a device.

  • Karlooie

    Hi @nicraboy:disqus , I read some of your comments on Cordova App not being able to run in background on Android 5+.

    Can you please elaborate a bit:

    iOs is possible to launch the cordova app when entering the range of a specified beacon?

    My need is to connect to the beacon when it’s in range, even if the app is not runnning.

    I did work with android background services for a different native app. Using services my goal should be possible, but I need to fork the plugin to have a service running and relaunching, that will scan for beacon and connect if found (I dont need to launch the cordova app at that time), correct?
    is there something similar in iOS? Are your aware of any cordova plugin to launch background services?

    thank you for the great article!

  • hi @NicNic Raboy, I followed your instructions for the demo, but nevertheless I got an error : ReferenceError: cordova is not defined at Object.requestWhenInUseAuthorization in the controller ( $cordovaBeacon.requestWhen…). My project is at github.com : https://github.com/henkjurriens/opendagapp/blob/master/www/templates/schools.html

    • Please paste your full logs. I’m not interested in seeing your code.

      • My logs :

        3 611351 log Ionic Deploy:, init

        3 611383 log Ionic Deploy:, init

        4 611465 error ReferenceError: cordova is not defined

        4 611485 error ReferenceError: cordova is not defined

        • What is this?:

          http://localhost:8100

          Am I correct in assuming that you’re using ionic serve, ionic view, or ionic live-reload? If I am correct, stop doing this. This is a native device plugin so you need to compile and then install the application to a device or simulator.

          Regards,

          • Thanks…you’re correct and I’ll stop doing this. I tried it on a simulator and it works 🙂

          • Yea, ionic serve, ionic live-reload, and ionic view should only be used in apps that use NO device plugins. In other words, simple apps that only do network requests and CSS stuff.

            Best,

  • ospfranco

    Hi Nic Raboy, I added the plugin (and wrapper) into an ionic project, however I get this error:

    Error: [$injector:unpr] Unknown provider: ngCordovaBeaconProvider <- ngCordovaBeacon <- ItemDetailCtrl
    http://errors.angularjs.org/1.4.3/$injector/unpr?p0=ngCordovaBeaconProvider%20%3C-%20ngCordovaBeacon%20%3C-%20ItemDetailCtrl
    at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:8895:12
    at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13089:19
    at Object.getService [as get] (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13236:39)
    at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13094:45
    at getService (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13236:39)
    at invoke (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13268:13)
    at Object.instantiate (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13285:27)
    at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:17841:28
    at I.appendViewElement (file:///android_asset/www/lib/ionic/js/ionic-angular.min.js:17:3709)
    at Object.H.render (file:///android_asset/www/lib/ionic/js/ionic-angular.min.js:16:17412)

    Any Idea what might be going on?

    • My guess is one of the following:

      You didn’t include the library in your index.html file
      You didn’t inject the library in your angular.module
      You didn’t inject the dependency in your controller
      You have a typo somewhere

      That is usually what the error means.

      Best,

  • Jason

    He Nic,

    Thanks for this awesome tut!
    I’m just starting to program and I figured I try this out. All seem to work except for the beacon detection.
    I’m using a custom chip which uses a Bluegiga BLE121LR. I set it’s UUID but the code doesn’t seem to get into the for loop.
    In turn my app’s screen stays blank. Should this be possible with any BLE device or only with the one’s specifically designed as iBeacon?

    Hope you can point me in the right direction.

    • The plugin that this uses expects the BLE signal to be iBeacon. This is why it doesn’t pick up other BLE items such as handsets.

      However, without seeing your logs, we won’t really know for sure whats happening in your case.

      • Jason

        He Nic,

        Thanks for your quick reply! This makes sense. For now I got it going by using a second phone with an app called “locate” this allows you to turn you android phone in a iBeacon 🙂

  • codapi

    Good tutorial and contrib, i’m using Firefox Os and the plugin doesn’t get anything and enter in the $rootScope.$on(“$cordovaBeacon:didRangeBeaconsInRegion”) event. But beacon is detected on bluetooth. And no logs error except “adding Proxy for device”

    • The plugin is for Android and iOS only. I believe Firefox OS is something else.

      Regards,

  • xonetar

    Hey there,

    i tried this but when i swipe away the apps from my running list of apps, it seems monitoring stops.

    Do you know how i can keep monitoring running as a background service?

    Thanks!

    • You probably want to ask this to the plugin developer. Android cannot run Apache Cordova processes in the background if the device is using 5.0 or higher. iOS should be fine.

  • Hi,

    I’m trying to get the application to work on my Android Device. I’m not receiving any errors what so ever.

    I have no trouble running it on my iOS device, it works perfectly! But when I try to run the same code on Android, it installs, looks normal but just isn’t showing nearby beacons.

    Plugins, ngcordova, android all have the latest version/update.

    Any ideas what might cause this problem?

    • Note: the ng-repeat in the BeaconController div –> ng-repeat=”(key, value) in beacons” stays empty! And still no debug or logging feedback

      • How are you checking for logs? I assume this is an Android device and not simulator correct? Are you sure you have bluetooth enabled?

        • Thanks for the fast reply. I’ve fixed it already. Turns out the company uses this android device a bit too much… Changed some hardware settings and it worked. Great tut and contribution btw;)

          • Awesome!

          • Ali

            Hi Koen,
            I have the same issue can you please tell me which settings do you fix .
            Thnx

  • Mehdi

    Hello @nicraboy:disqus ,
    You tutorial is great and helpful.
    I used it to list 8 beacons and their attributes plus RSSIs and accuracies. It works fine and list all beacons in both ios and android. However I faced an issue. In a given position, android device lists far beacons with some RSSI around -100 or less. But iOS just shows 0 for those beacons. For nearby beacons (in range of < 4 meters), both ios and android show rather same RSSIs.
    What do you think about this discrepancy?
    Thanks

    • That is something you should probably bring up to the plugin developer. I only made a wrapper to the actual plugin. If there are bugs in the plugin, the developer would be the guy to ask 🙂

    • Matthew Rodriguez

      Hello @disqus_VshszFm5hw:disqus,

      I am having a similar issue. Did you contact the plugin developer as @nicraboy:disqus suggested?

  • Dipak

    Thanks, really helpful. Do you have any suggestions on how to modulate and configure package in ionic2 ? DO you have any different article for that?

    • I was thinking about making a wrapper for Ionic 2, but I have not yet. Check back in a few weeks.

      • Dipak

        Sure, we all waiting for that. Is there any other docs I can refer to do it.

  • Ali

    Hi NIc,
    Thanks for this tuto.
    I do the same thing here but still not working with android. Do you have any idea why ?

  • ha1ku

    Hi @nicraboy:disqus. For reasons I don’t yet fully understand, your example implementation works while the $cordovaBeacon service at ngcordova.com doesn’t. Thanks to you and Elizabeth for the fine work!

    (A couple things are present in your example code that aren’t obvious at ngcordova: $broadcasted events, and a deviceready event handler. Maybe that’s the significant difference?)

    • I don’t know anything about the ngCordova version. If mine works better for you, go ahead and use it 🙂

  • Manuel Guillen

    Hi Nic, excellent tutorial. I tried to use the plugin in an ionic 2 app. I solved the ‘cordova is not defined’ error with ‘declare var cordova:any’ before the first @ (component, inject). The enable/disable bluetooth works fine, but when i invoke a delegate with ‘new cordova.plugins.locationManager.Delegate();’ i receive that error (cordova is not defined). Do you have any example with Ionic 2? Thanks, your post help me a lot.

    • Please put your code on GitHub and I’ll have a quick look.

      • faisal farooq

        @disqus_SMJ7ohRBK3:disqus Can you please share you ionic 2 beacon app code? I am struggling with the same problem. Thanks.

  • Chael Gutierrez

    sir @nicraboy:disqus can you help me detect specific beacon in an area? using ionic framework and have a success call back if detected?

  • Mohammad Al-mouallem

    Hi @nicraboy:disqus I noticed the Angular wrapper use alot of broadcasting to the rootScope wouldn’t make the performance low? is not better to use the original plugin instead ?

    • The original plugin is not Angular friendly. In most scenarios you’re going to want the beacon data to end up in the scope anyways. I can’t imagine the broadcasting causing any performance issues.

      • Mohammad Al-mouallem

        Hi! true it is not Angular friendly but still usable, my thoughts are the $rootScope.$watch list will get longer which might cause performance issue. However if am passing the beacon data to a service which call an end point do I still having the data in the scope !
        Thank you for your time.

  • Suresh

    Hi Nic,
    Is the NG-cordova Wrapper from GIT-hub still active ??, i cannot able to pull this from GIT through CLI, but when i added the file manually, it reported error that cordova is undefined. Let me know if you have any suggestions on solving this.
    Thanks for your support

    • Well, ng-cordova-beacon is not a Cordova plugin. It is a JavaScript library. I didn’t put anywhere in this guide that it should be installed like such.

      You might want to go through the guide from start to finish again. Yes it still works fine.

      Best,

  • imran syed

    Hi, I am new to this so hoping to get some pointers. I bought some unbranded beacons which supports ibeacon and eddystone , they have provided me with SDK both for ios and android. Im trying to develop an ionic app with cordova plugin to communicate and manage these beacons. How do I go about this? where do I start?

    • The Apache Cordova plugin is read only. It will not configure your iBeacons. You need to read the manufacturer guides for that one.

      Once you have configured your beacons to use the iBeacon spec (not Eddystone), then you can follow this guide. This guide will not work with Eddystone configuration.

      Best,

      • imran syed

        Thanks Nic. I do have the manual and it was shipped with default UUID and I did not bother to change it. Then I used the app ‘skybeacon’ to connect to the beacon. It successfully connects and disconnects in 10 sec throwing error ‘The peripheral has disconnected’ the connection is stale. Any idea what this error is? Some sort of timer?

        • You do not connect to iBeacons. They do not pair like other bluetooth devices.

          If you’re just getting started with beacons you might consider Gimbal or Radius Networks. They have quality docs and tooling for configuring your beacons.

          Best,

  • Mohammad Al-mouallem

    Hi @nicraboy:disqus I see the plugin working fine without the need to invoke the startMonitoringForRegion method. How is that working ! and if so what is the use of the method startMonitoringForRegion ?

  • Harith Rosli

    hi, can i know on how to stop ranging?

  • Suresh

    Hi Nic,
    Any plans for updating the tutorial for ionic2..
    Thanks
    Suresh

    • When time permits I will create an Angular 2 version of this library.

      Best,

      • Francesco Boccassi

        Hi Nic,

        have you created the Angular 2 library? It would be very usefull!
        Kind regards

        • I will no longer be creating an Angular 2 library as I’ve discontinued my development with Ionic Framework and Ionic 2.

          • Frameworks

            why ??

          • Creating a library is a lot of work and typically requires support. My opinions of Ionic are no longer very high, so I’d rather not put time into something I don’t really believe in.

            Best,

  • Mandar Shirke

    @Nic Raboy I’m trying hard since 2 days but I’m unable to get this app work. Tried with multiple beacons & devices. here is my code : https://github.com/quadcodes/ionicbeacon

    • I’d rather see your logs than your code.

      • Mandar Shirke

        Thank you for the reply. I found out the issue finally !! Waiting for your Angular 2 version of this library now !!! 🙂

  • Enrique Gomez

    hello, i work with stimote ibeacons in this moment. and i have a question, woh i can send avertisement with ibeacons??.

    • iBeacons do not broadcast ads. They broadcast UUID strings that you should map to data via a database.

  • Carlos

    I’ve created a Git repo with my implementation for the above article (https://github.com/cballock/ionic-beacon). I’ve tested in my iPhone 6 (iOS 10) and it’s working.

  • Los

    Hi @nicraboy:disqus

    I’ve been trying to follow this tut for 3 months now (with a lot of give ups) and i get the same error everytime no matter what I try (even copy and paste does not work). When I run the app (with ionic run android) my android device 4.4.2 displays this:
    “Major: {{value.major}} minor:{{value.minor}} {{value.proximity}}”.

    Can you please help point what at i’m doing wrong?

    I am new to programming and I am learning. I am not sure how to get the relevant log when running on a real device but when I “run ionic serve” I get the same display as above with the below errors below attached errors:

    “ng-cordova-beacon.min.js:5 Uncaught SyntaxError: Unexpected token <
    ionic.bundle.js:17917 Uncaught Error: [$injector:modulerr] Failed to instantiate module starter due to:
    Error: [$injector:modulerr] Failed to instantiate module ngCordovaBeacon due to:
    Error: [$injector:nomod] Module ‘ngCordovaBeacon’ is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
    http://errors.angularjs.org/1.5.3/$injector/nomod?p0=ngCordovaBeacon
    at http://localhost:8100/lib/ionic/js/ionic.bundle.js:13438:12
    at http://localhost:8100/lib/ionic/js/ionic.bundle.js:15404:17
    at ensure (http://localhost:8100/lib/ionic/js/ionic.bundle.js:15328:38)
    at module (http://localhost:8100/lib/ionic/js/ionic.bundle.js:15402:14)
    at http://localhost:8100/lib/ionic/js/ionic.bundle.js:17894:22
    at forEach (http://localhost:8100/lib/ionic/js/ionic.bundle.js:13691:20)
    at loadModules (http://localhost:8100/lib/ionic/js/ionic.bundle.js:17878:5)
    at http://localhost:8100/lib/ionic/js/ionic.bundle.js:17895:40
    at forEach (http://localhost:8100/lib/ionic/js/ionic.bundle.js:13691:20)
    at loadModules (http://localhost:8100/lib/ionic/js/ionic.bundle.js:17878:5)
    http://errors.angularjs.org/1.5.3/$injector/modulerr?p0=ngCordovaBeacon&p1=…%3A%2F%2Flocalhost%3A8100%2Flib%2Fionic%2Fjs%2Fionic.bundle.js%3A17878%3A5)
    at http://localhost:8100/lib/ionic/js/ionic.bundle.js:13438:12
    at http://localhost:8100/lib/ionic/js/ionic.bundle.js:17917:15
    at forEach (http://localhost:8100/lib/ionic/js/ionic.bundle.js:13691:20)
    at loadModules (http://localhost:8100/lib/ionic/js/ionic.bundle.js:17878:5)
    at http://localhost:8100/lib/ionic/js/ionic.bundle.js:17895:40
    at forEach (http://localhost:8100/lib/ionic/js/ionic.bundle.js:13691:20)
    at loadModules (http://localhost:8100/lib/ionic/js/ionic.bundle.js:17878:5)
    at createInjector (http://localhost:8100/lib/ionic/js/ionic.bundle.js:17800:19)
    at doBootstrap (http://localhost:8100/lib/ionic/js/ionic.bundle.js:15080:20)
    at bootstrap (http://localhost:8100/lib/ionic/js/ionic.bundle.js:15101:12)
    http://errors.angularjs.org/1.5.3/$injector/modulerr?p0=starter&p1=Error%3A…3A%2F%2Flocalhost%3A8100%2Flib%2Fionic%2Fjs%2Fionic.bundle.js%3A15101%3A12)
    75livereload.js?snipver=1:191 WebSocket connection to ‘ws://localhost:35729/livereload’ failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED”

    • “ng-cordova-beacon.min.js:5 Uncaught SyntaxError: Unexpected token < leads me to believe you have a typo somewhere in your code. Maybe a stray bracket. Make sure you don’t have any typos and that you’ve downloaded the library, included it in your index file, and injected it in your AngularJS code. Should work after that.

      In terms of Ionic Serve, I would recommend against it. Native plugins tend to not work properly with it.

      Best,

  • MSS

    Hi, I have an existing ionic app and want to incorporate beacons to notify members when they arrive on the location. I am looking for a developer.. can you help with this project?

  • faisal farooq

    Can someone please guide for a resource to do the same thing with ionic 2 and estimote beacons. thanks.

  • Ben M.

    hi @nicraboy:disqus how can i get the scan in the background and trigger a notification when a specifique beacon has been detected.