Update 6 August 2014: If you want to use up-to-date plugins, please beware the EasyFB approach isn’t going to work any more, so you might not get much out of this post. 🙁
I thought that getting Phonegap, AngularJS and Facebook working together couldn’t be a big jump from the simple quickstart guides available for each of those components. This was probably naïve.
It’s a nightmare
If any part of the above are new to you, starting out can be confusing and poorly documented. If, like me, you’re a newbie with both Phonegap and Angular… it’s worse.
Perhaps it’s because most of the constituent parts are changing so fast at the moment – despite myriad posts out there on each of the technologies involved, it took me absolutely ages to get it all working as I wanted, and even longer to replicate the steps reliably enough to write this!
As I never really found an article or post with my exact goals and a full explanation all in one place, hopefully this one might make the process less of a time sink for anyone taking the same route.
The plan
I’m making an app which will offer authentication and friend-related features on mobile. My goals for an initial starting point were to:
- Run on (at least) Android & iOS
- Use Phonegap
- Use AngularJS in something approaching the ‘right’ way, with a reasonable stab at proper MVC separation of concerns – ideally even when dealing with Facebook’s JavaScript
- Use Facebook via the Phonegap plugin, with native dialogs where possible
Why not a mobile site?
Partly to make it easier to build features that work offline and keep things flexible; partly in the hope of making a ‘more native’ user experience. I was also keen to try out building a (pseudo-)native app.
Why not true native?
I know web development, whereas I’ve not done much lately with Java and nothing with Objective-C. I’m also keen to avoid maintaining 2 codebases in tandem if possible. My app should be simple enough in terms of visuals that the performance penalty won’t be a major issue on most devices.
Why Phonegap over others?
It seems the open source effect means that right now there is a bit more of a community focus and info out there for Phonegap than for e.g. Trigger.io. The latter might be a bit easier to get started with, but they also want $468/yr for the cheapest plan – which comes with only community support. Given I’ll initially be making and distributing this app for free, that didn’t strike me as great value. Don’t get me wrong, I was still considering it at points during the process of figuring out a Phonegap solution!
But enough background – let’s get set up and find some answers.
Pre-requisites
I’ll explain what I did on OS X and building for iOS – the steps are likely to differ a bit on another OS. I’ve tried this out from scratch with Phonegap 3.4.0 so it should work with that version if you’re following along. The easiest way to get Phonegap is probably to get Node.js and NPM (perhaps with Homebrew).
You’ll want Bower and a Yeoman-based starter project too – so that’s:
npm install -g phonegap npm install -g bower npm install -g generator-angular-phonegap-seed
If you don’t have your Facebook app set up yet you’ll need to make one here.
You’ll also need to install the Facebook SDK, and probably Xcode.
Initial project
Use the handy Angular + Phonegap seed as your starting point. If you don’t already have a project, you can fire up Terminal or equivalent and do something like:
phonegap create demoapp --name demoapp --id com.noellh.demoapp cd demoapp yo angular-phonegap-seed
Then give a name (e.g. demoapp
again) at the interactive prompt and answer Yes if you’re happy to nuke the old index.html
.
This bit’s easy thanks to this scaffolding project. You now have Phonegap and AngularJS working, with views set up in the proper Angular way.
config.xml
We’re getting slightly ahead of ourselves, but in order to make all the changes at once, let’s jump into our project’s www/config.xml
now.
- Set the
id
on<widget>
to a suitable bundle ID, e.g.com.noellh.demoapp
- Set the
<name>
- Update the access policy at the bottom – the simplest option is
<access origin="*"/>
- Add the plugin sections somewhere inside
<widget>
. We’ll only finish setting up iOS in this post, but for both platforms this looks like:<feature name="org.apache.cordova.facebook.Connect"> <param name="android-package" value="org.apache.cordova.facebook.ConnectPlugin" /> </feature> <feature name="org.apache.cordova.facebook.Connect"> <param name="ios-package" value="FacebookConnectPlugin" /> </feature>
You could add the Phonegap Build plugin code too if you think you might use it – you’ll need your app ID & name.
Add the Facebook plugin
I wanted the option of developing locally, so didn’t want to be dependent on Phonegap Build for the plugin setup. Manual setup of the Phonegap Facebook plugin was a pretty unpleasant process until very recently. The section of the docs about ‘Plugman’, which allows for automatic installation, consisted only of a dire warning that it was broken. Fortunately this has since been replaced with instructions and a working Plugman setup. I focused on iOS for this walkthrough as I found it more complicated initially – with the introduction of Plugman Android might actually have become the more fiddly platform, but it is at least now documented!
So, to get Facebook in your project:
- Download the Phonegap Facebook plugin.
- Do the following, where the path points to your download of the plugin and the number is your Facebook app ID:
phonegap build ios cordova -d plugin add /.../phonegap-facebook-plugin --variable APP_ID="12345" --variable APP_NAME="demoapp"
- While this does ‘most’ of the setup through Plugman, I had to manually fix the plugin references, which I think is a bug. Start by navigating in your project to
platforms/ios/demoapp.xcodeproj
and open it in Xcode. - Open up the file list on the left, and open Plugins at the top level. If you have both
Facebook...
items showing in red, delete them. - Then follow the manual steps for adding these: make a group
ios
, drag the 2 files into that, and opt to copy them to the project. You should find the files in your project underplugins/com.phonegap.plugins.facebookconnect/src/ios
. You can ignore the frameworks folder there. - You should now see those plugin files inside the
ios
group and not highlighted in red.
One more thing before we start trying to use the plugin: edit your Facebook app settings to add the iOS platform, and fill in your bundle ID (e.g. com.noellh.demoapp
) under Settings > Basic > iOS > Bundle ID.
EasyFB
Next, we want to be able to use the plugin without messing up our AngularJS project structure and proper scoping with messy Facebook JavaScript. Enter EasyFB for AngularJS.
It looks like this only started working with Phonegap a couple of months ago, and I’m very very grateful for its existence. I was really struggling to get the global FB
from the SDK into Angular controllers in a way that was clean, in line with Angular style and actually worked. This helped a lot!
- If you share my enthusiasm for being able to use Bower at will, but would rather stick to using
www/lib
and notbower_components
, you might want to make a file called.bowerrc
in your project root containing:{ "directory" : "www/lib" }
- Then from Terminal:
bower install angular-easyfb
- In your
index.html
, add to the end of the libs, immediately afterangular-route.js
:<script src="cdv-plugin-fb-connect.js"></script> <script src="facebook-js-sdk.js"></script> <script type="text/javascript" src="lib/angular-easyfb/angular-easyfb.js"></script>
Don’t worry that the first 2 don’t exist, and don’t copy them in – they will be ‘injected’ by Phonegap as with
phonegap.js
itself.
The home straight
- Now you just need to use all this stuff in your app! To make things quicker you might want to borrow from this Gist with my demo files.
main.html
replaces the one inwww/partials
and the JS files are inwww/js
. This probably doesn’t use the EasyFB methods in the best way, but it should be enough to check things are working – if so it will show your name after you connect. - If you copy the files from the Gist, remember to replace
12345
with your app ID inapp.js
, and replace alldemoapp
s with your own app name in both JS files. - The moment of truth:
phonegap run ios
All being well, you should have working Angular routes, and the main view contains the Facebook demo.
Phew!
I hope this might save somebody some time getting an app off the ground with the same technologies. Any comments on alternatives or ideas about how to make this simpler would be very welcome!
Versions used for final run through
- Phonegap 3.4.0
- Facebook iOS SDK 3.14
- Phonegap Facebook plugin 0.5.0
- AngularJS 1.3.0
- angular-easyfb 1.0.1
- generator-angular-phonegap-seed 0.6.0
- yo 1.1.2
- Bower 1.3.3
- OS X 10.9.2
- XCode 5.1.1
“It’s a nightmare”…. exactly!
The whole angular/phonegap/facebook stack is sorely lacking clear and concise (and working!!) examples. Your gist was very helpful – had to modify to use facebookConnectPlugin.js, but then it worked a treat.
FYI, the ‘develop’ branch of the phonegap-facebook-plugin had the only example that worked for me (android). For some reason, this was based on facebookConnectPlugin.js rather than cdv-plugin-fb-connect.js.
@Dunc can you please the code modification you did with facebookConnectPlugin.js.
I am using that one and I am stuck, I constantly get errors.
Thank you in advance
Besa