README.md in motion-firebase-2.1.5 vs README.md in motion-firebase-3.0.0

- old
+ new

@@ -5,25 +5,43 @@ Adds more rubyesque methods to the built-in classes. For a Ruby (MRI) Firebase wrapper, check out <https://github.com/derailed/bigbertha>. -Versioning -------- +Installation +============ -Versioning matches Firebase's SDK major and minor version numbers, but revision -numbers could be different. +The **motion-firebase** gem ships with "freeze dried" copies of the Firebase +framework. This way we can guarantee that the version of **motion-firebase** is +*definitely* compatible with the version of Firebase that is included. As new +features get announced, we update the gem. -SDK ---- +Also, it means that installation is easy! When you compile your RubyMotion +project, the Firebase SDK gets included automatically. -# Firebase Class Reference +motion-firebase 3.0 +======== +Lots of changes in this version: <3.0.md> + +# SDK + ##### Initializing a Firebase object ```ruby Firebase.new(url) + + # it's common to set a global firebase URL. Set it in your app delegate, + # and calling `new` will use that default URL. + Firebase.url = 'https://your-app.firebaseio.com' + Firebase.url # => 'https://your-app.firebaseio.com' + Firebase.new + + # these all work, too: + Firebase.url = 'your-app.firebaseio.com' + Firebase.url = 'your-app' + Firebase.url # => 'https://your-app.firebaseio.com' ``` ##### Getting references to children locations ```ruby @@ -70,11 +88,21 @@ firebase.set(last_name: 'firebase') # first_name is now 'nil' ``` ##### Attaching observers to read data +[Events](https://www.firebase.com/docs/web/guide/retrieving-data.html) can have the value of: + ```ruby +:child_added, :added, FEventTypeChildAdded +:child_moved, :moved, FEventTypeChildMoved +:child_changed, :changed, FEventTypeChildChanged +:child_removed, :removed, FEventTypeChildRemoved +:value, FEventTypeValue +``` + +```ruby handle = firebase.on(event_type) { |snapshot| 'completion block' } handle = firebase.on(event_type) { |snapshot, previous_sibling_name| 'completion block' } handle = firebase.on(event_type, completion: proc { |snapshot, previous_sibling_name| 'completion block' }, disconnect: proc { 'completion block' } @@ -105,10 +133,16 @@ # => firebase.queryStartingAtPriority(priority) firebase.start_at(priority, child: child_name) # => firebase.queryStartingAtPriority(priority, andChildName: child_name) + firebase.equal_to(priority) + # => firebase.queryEqualToPriority(priority) + + firebase.equal_to(priority, child: child_name) + # => firebase.queryEqualToPriority(priority, andChildName: child_name) + firebase.end_at(priority) # => firebase.queryEndingAtPriority(priority) firebase.end_at(priority, child: child_name) # => firebase.queryEndingAtPriority(priority, andChildName: child_name) @@ -117,50 +151,44 @@ # => firebase.queryLimitedToNumberOfChildren(limit) ``` ##### Managing presence +SOO COOL! Play with these, you can *easily* create a presence system for your +real-time app or game. + ```ruby - firebase.online! - firebase.offline! - firebase.connected_state # returns a Firebase ref that changes value depending on connectivity + Firebase.online! + Firebase.offline! + Firebase.connected? # returns a Firebase ref that changes value depending on connectivity + + # or you can pass in a block, this block will be called with the connected + # state as a bool: + handler = Firebase.connected? do |connected| + if connected + # so awesome + end + end + # you should turn it off when you're done, otherwise you'll have a memory leak + Firebase.off(handler) + + # so what you do is get a ref to the authenticated user's "presence" value. + # Then, on_disconnect, set the value to 'false'. firebase.on_disconnect(value) # set the ref to `value` when disconnected firebase.on_disconnect(value) { |error| 'completion block' } firebase.on_disconnect(value, priority: priority) firebase.on_disconnect(value, priority: priority) { |error| 'completion block' } firebase.on_disconnect(nil) firebase.on_disconnect(nil) { |error| 'completion block' } firebase.on_disconnect({ child: values }) firebase.on_disconnect({ child: values }) { |error| 'completion block' } + + # sometimes you need to cancel these 'on_disconnect' operations firebase.cancel_disconnect firebase.cancel_disconnect { |error| 'completion block' } ``` -##### Authenticating - -```ruby - firebase.auth(secret_key) - firebase.auth(secret_key) { |error, data| 'completion block' } - firebase.auth(secret_key, - completion: proc { |error, data| 'completion block' }, - disconnect: proc { |error| 'completion block', }, - ) - # calls `unauth`, or if you pass a block calls `unauthWithCompletionBlock` - firebase.unauth - firebase.unauth do |error| - # ... - end - # when using FirebaseSimpleLogin to authenticate, this child node should be - # monitored for changes - firebase.auth_state - # usually you'll want to monitor its value, so this is a helper for that: - handle = firebase.on_auth do |snapshot| - end - # be a good citizen and turn off the listener later! - firebase.off(handle) -``` - ##### Transactions ```ruby firebase.transaction do |data| current_value = data.value @@ -202,74 +230,174 @@ ##### Global configuration and settings ```ruby Firebase.dispatch_queue=(queue) Firebase.sdkVersion + Motion::Firebase::SdkVersion # this string is more human readable than sdkVersion ``` -# FirebaseSimpleLogin Class Reference - require 'motion-firebase-auth' +# Firebase Authentication Reference -##### Initializing a FirebaseSimpleLogin instance +Most of the authentication methods can be called statically as long as you have +set a default `Firebase.url` +##### Checking current authentication status + ```ruby - ref = Firebase.new(url) - auth = FirebaseSimpleLogin.new(ref) + Firebase.authenticated? # => true/false + # you pretty much always need to hold a reference to the "handler" + auth_handler = Firebase.authenticated? do |auth_data| + if auth_data + # authenticated! + else + # not so much + end + end + # turn off the handler, otherwise, yeah, memory leaks. + Firebase.off_auth(auth_handler) ``` -##### Checking current authentication status +##### Authenticate with previous token ```ruby - auth.check { |error, user| } + Firebase.auth(token) do |error, auth_data| + end ``` ##### Removing any existing authentication ```ruby - auth.logout + Firebase.logout ``` -##### Email/password authentication methods +## Email/password authentication methods -`credentials` for `create,remove,login` should include `:email` and `:password`. -For `update`, `credentials` should include `:email`, `:old_password` and -`:new_password`. +This is the most common way to login. It allows Firebase to create users and +tokens. ```ruby - auth.create(email: 'hello@example.com', password: '12345') { |error, user| } - auth.remove(email: 'hello@example.com', password: '12345') { |error, user| } - auth.login(email: 'hello@example.com', password: '12345') { |error, user| } - auth.update(email: 'hello@example.com', old_password: '12345', new_password: '54321') { |error, success| } + Firebase.create_user(email: 'hello@example.com', password: '12345') { |error, auth_data| } + Firebase.remove_user(email: 'hello@example.com', password: '12345') { |error, auth_data| } + Firebase.login(email: 'hello@example.com', password: '12345') { |error, auth_data| } + Firebase.login_anonymously { |error, auth_data| } + Firebase.update_user(email: 'hello@example.com', old_password: '12345', new_password: '54321') { |error, success| } + + auth_data.uid # is a globally unique user identifier + auth_data.token # can be stored (in a keychain!) to authenticate the same user again later ``` -##### Facebook authentication methods +See <https://www.firebase.com/docs/ios/api/#fauthdata_properties> for other +`auth_data` properties. -`credentials` must include `:app_id`. `:permissions` defaults to `['email']` and -`:audience` defaults to `ACFacebookAudienceOnlyMe`. +## Other authentication providers + +##### Facebook authentication + +This Facebook helper is a port of the Objective-C code from +<https://www.firebase.com/docs/ios/guide/login/facebook.html>. + ```ruby - auth.login_to_facebook(app_id: '123abc') { |error, user| } + Firebase.open_facebook_session( + permissions: ['public_profile'], # these are the default values. if + allow_login_ui: true, # you're OK with them, they are + ) do |error, auth_data| # optional, so just provide a block. + end ``` -##### Twitter authentication methods +##### Twitter authentication -`credentials` should include `:app_id` and `:on_multiple` block. The -`:on_multiple` block is called when more than one account is found. It is -passed an array of usernames and should return an index or `NSNotFound`. +This Twitter helper is a port of the Objective-C code from +<https://www.firebase.com/docs/ios/guide/login/twitter.html>. You should read +that page to see how Firebase recommends handling multiple accounts. It's a +little streamlined here, since `open_twitter_session` returns a block that you +can call with the chosen account. ```ruby - auth.login_to_twitter(app_id: '123abc', on_multiple: ->(usernames) { return 0 }) { |error, user| } + # it's nice to be able to set-and-forget the twitter_api_key (in your + # application delegate, for example) + Firebase.twitter_api_key = 'your key!' + + # You must set Firebase.url=, or call open_twitter_session on an existing + # Firebase ref. The first step is to get the Twitter accounts on this + # device. Even if there is just one, you need to "choose" it here. Also, + # you can pass the twitter api_key as an option, otherwise this method will + # use Firebase.twitter_api_key + Firebase.open_twitter_session(api_key: 'your key!') do |error, accounts, next_step| + # next_step is a block you call with the chosen twitter account and a + # firebase handler for the authentication success or failure + if error + # obviously do some stuff here + else + present_twitter_chooser(accounts, next_step) do |error, auth_data| + # this block is passed to next_step in present_twitter_chooser + if error + # bummer + else + # awesome! + end + end + else + end + + def present_twitter_chooser(accounts, next_step, &firebase_handler) + if accounts.length == 1 + next_step.call(accounts[0], &firebase_handler) + else + # present a controller or action sheet or something like that + ... awesome twitter account chooser code ... + next_step.call(account, &firebase_handler) + end + end ``` -##### Global configuration and settings +##### Github authentication +Firebase doesn't provide much help on this one. I'm not even sure *how* to get +a github access token from the user... but anyway here's the `motion-firebase` +code based on <https://www.firebase.com/docs/ios/guide/login/github.html>. + ```ruby - FirebaseSimpleLogin.sdkVersion + Firebase.github_token = 'github oauth token' + Firebase.open_github_session do |error, auth_data| + end ``` -##### Retrieving String Representation +##### Google authentication +This process is more involved, and relies on the GooglePlus framework. I didn't +take the time to port the code this time, but I hope someone does someday! 😄 + +You can read Firebase's instructions here: <https://www.firebase.com/docs/ios/guide/login/google.html> + ```ruby - firebase.to_s - firebase.inspect + Firebase.google_token = 'google oauth token' + Firebase.open_google_session do |error, auth_data| + end +``` + +##### Generic OAuth Authentication + +Usually you will use the helpers from above, but here are some lower level +methods: + +```ruby + # using a token + firebase_ref.login_to_oauth(provider, token: token) do |error, auth_data| .. end + firebase_ref.login_to_oauth(provider, token) do |error, auth_data| .. end + + # using parameters + firebase_ref.login_to_oauth(provider, oauth_token: token, oauth_token_secret: secret) do |error, auth_data| .. end + params = { ... } + firebase_ref.login_to_oauth(provider, params) do |error, auth_data| .. end + + # which is a wrapper for these SDK methods: + firebase_ref.authWithOAuthProvider(provider, token: token, withCompletionBlock: block) + firebase_ref.authWithOAuthProvider(provider, parameters: params, withCompletionBlock: block) + + # Again, the `open_*_session` methods are even more convenient. + firebase_ref.login_to_facebook(facebook_access_token, &block) + firebase_ref.login_to_twitter(token: token, secret: secret, &block) + firebase_ref.login_to_github(github_oauth_token, &block) + firebase_ref.login_to_google(google_oauth_token, &block) ```