X
X

Login

Login if you already have an account

LOGIN

Register

Create a new account. join us!

REGISTER

Support

Need some help? Check out our forum.

FORUM

FatFractal ups the ante in Backend-as-a-Service market

Anyone who has developed a smartphone app would have set up servers and built backend services such as location services to support the app. You could do this on your own servers, or tap on IaaS and PaaS providers like Amazon Web Services (AWS) and Cloud Foundry.

But whether you choose to build and host your app in-house or through the cloud, you’d still need to deal with social media integration and set up virtual machines, user profile services, and more.

The Market:

In the past year, a handful of startups have formed a new category of cloud services known as backend-as-a-service (BaaS) to ease the task of setting up the nuts and bolts for running mobile apps. The new players such as Kinvey, Parse, CloudMine and more recently, FatFractal, all provide mobile backend services such as data storage, push notifications and user management.

“The BaaS players are providing application developers with an instant backend so that they don’t have to manage one,” says FatFractal’s chief marketing officer David Lasner.

While developers can turn to the likes of AWS to build a mobile backend, they have to configure their cloud infrastructure extensively, such as defining an event model that triggers what happens when a user, say, checks in at the same location several times a week.

“And you’re wiring it all together every time you want build an application,” Lasner says.

What we were looking for is something that would give you the native code support, an event model and security that works, so you can stop using the heavy stuff on the enterprise side. You have some pretty smart people out there, but it was still incredibly hard to build these cloud-based apps. That’s why we built the FatFractal platform,” he adds.

Upset the Status Quo:

The new BaaS offerings have the potential to upset the status quo in enterprises that typically control who develops apps and how apps should be developed, says FatFractal’s president Kevin Nickels.

“At the strategic level, they should think about how every employee should be able to write an app, or that customers should be able to write their own apps and access corporate information they way they want to. That’s a really hard thing for an IT department to wrap its head around,” he says.

According to Lasner, FatFractal took about two years to build and allows programmers to write applications in native environments such as Java and Objective C.

“You’ll also get out of the box services integrated in your object oriented world that allows you to do some complex modeling,” he says, “I often joke that if the Facebook team used the FatFractal platform, all the problems they had with the privacy of photos and groups would have taken a month to resolve.”

FatFractal also provides access into the backend, which not all BaaS players allow, according to Lasner. “That’s a problem because if you’re going build a software architecture for the cloud, most of the heavy lifting should happen on the backend. So, while it’s great to not think about data stores, I also want my business logic, events model and custom code to run on the backend”.

As an engine-based platform, FatFractal also allows developers to use familiar technologies to write apps and run the platform, including data stores and services, locally on their own PCs before deploying to the cloud. “Developers love to build things on their own machines because all the tools they’re using are available there, and you don’t have to rely on a network.”

A concern among companies considering BaaS services is the risk that service providers could change pricing models or go bust. Lasner assures developers that there is no vendor lock-in with FatFractal, as the platform uses the same data models in standard programming languages such as Java. That means you can move your app to another infrastructure service or platform, Lasner says.

How developers will take to FatFractal and the other BaaS offerings remains to be seen. After all, to developers, IaaS, PaaS and BaaS are merely different parts of the larger cloud infrastructure required to run their apps.

As Nickels puts it, “there is no need for BaaS to be separate from PaaS; there are no separate markets and at some point, they are going to collapse into a single definition”.

By: Aaron Tan

Permissions can be inherited from other objects (pretty slick!)

As a Developer, I want to be able to implement access control policies that are inherited from another object so that I can easily propagate access control policies within my application.

If you want to set a default permission for objects in a collection that inherit permissions from another object, it is super easy using FFDL (what is FFDL?).

Example:

Say you have a Collection of JokeBook objects with permission defaults set and another Collection of Joke objects that have a reference to a JokeBook and you would like your Joke objects to inherit their default permissions from JokeBook objects. OK – short version is that I want the permissions for a Joke to be the same as the JokeBook they refer to.

The FFDL would look something like:

# JokeBook
CREATE OBJECTTYPE JokeBook (title STRING, writers REFERENCE /FFUserGroup, readers REFERENCE /FFUserGroup)

CREATE COLLECTION /JokeBooks OBJECTTYPE JokeBook
PERMIT read:object.readers write:object.writers ON /JokeBooks

This defines a JokeBooks Collection that contains Jokebook Objects that have a title, a reference to an author, a reference to a group of users with write access named writers and a group of users with read access named readers.

# Joke
CREATE OBJECTTYPE Joke (setup STRING, punchline STRING, book REFERENCE /JokeBook)

CREATE COLLECTION /Jokes OBJECTTYPE Joke

PERMIT read:object.book.readers write:object.book.writers ON /Jokes

This defines a Jokes Collection that contains Joke Objects which have a reference called “book” from the JokeBooks Collection:

book REFERENCE /JokeBooks

So, you will notice that read and write permissions for a Joke object are set to refer to the read and write permissions (respectively) that are defined for the JokeBook object referred to by the “book” member.

PERMIT read:object.book.readers, write:object.book.writers ON /Jokes

Voila! Now the Joke object has the same permissions as the JokeBook object – as easy as that!

Of course, this is the default setting and you can always change the access to any particular object programmatically in your application code.

Hope you find this useful!!

For more details, see the FFDL documentation here.

To see the other things you can do with permissions see here.

FYI – FatFractal Makes File Upload Easy

You can access the source code for the sample application here.

Inspired by a recent blog post by Raymond Camden, we decided to show how much easier FatFractal makes it to create an object containing a blob. This example uses our JavaScript SDK in a PhoneGap app, but all of our SDKs feature the same ease of use.

Here’s the relevant code for uploading with FatFractal:

// Not even a little bit complex -- just set the member
var newNote = {
clazz: "Note",
text: noteText
};
if (imagedata) newNote.picture = imagedata;
ff.createObjAtUri(newNote, "/Note", function(result) {
$.mobile.changePage("#home");
}, function(error) {
console.log("Oh crap", error);
});
cleanUp();
Here’s the Parse code (from Raymond Camden’s blog):
/*
A bit complex - we have to handle an optional pic save
*/
if (imagedata != "") {
var parseFile = new Parse.File("mypic.jpg", {base64:imagedata});
console.log(parseFile);
parseFile.save().then(function() {
var note = new NoteOb();
note.set("text",noteText);
note.set("picture",parseFile);
note.save(null, {
success:function(ob) {
$.mobile.changePage("#home");
}, error:function(e) {
console.log("Oh crap", e);
}
});
cleanUp();
}, function(error) {
console.log("Error");
console.log(error);
});
} else {
var note = new NoteOb();
note.set("text",noteText);
note.save(null, {
success:function(ob) {
$.mobile.changePage("#home");
}, error:function(e) {
console.log("Oh crap", e);
}
});
cleanUp();
}
(The only other significant change was to switch to reading the image from the filesystem rather than receive it as a base64-encoded string, which is arguably better practice anyway. Check out the full source up on GitHub!)

So, instead of forcing you to create and save a special file object, FatFractal lets you do the natural thing: you set the member, we take care of the rest.

FYI – user management – Part I

We get asked a lot about how to customize the user definition (FFUser) with FatFractal. This post describes two methods to add some custom information about the user to the system. Either is fine, and there are some important distinctions regarding access control that you may want to consider. I will be adding more user management use cases in future blog posts. For now, let’s start with the basics and that is subclassing FFUser as well as creating a reference object with the required additional information as an alternative approach.

As usual – I have included source code and a sample application (actually three of them) to further illustrate. For this post, the code is written as test cases and include iOS, Android and HTML5/JS versions.

The source code for the sample applications is here.

A working sample test app is here

Update: Feb 14
Introduced FFUserProtocol – no longer need to subclass FFUser if introducing a custom ‘user’ class – simply have it implement the FFUserProtocol. FFUserProtocol is defined in FFUser.h as follows


@protocol FFUserProtocol
@property (strong, nonatomic) NSString          *guid;
@property (strong, nonatomic) NSString          *userName;
@end

All methods which previously took FFUser as parameters will now accept any class which implements the FFUserProtocol

Method 1: MyFFUser as a subclass of FFUser

The first method is to subclass the FFUser class that is included in all the SDKs. The example here adds three parameters to the definition – including a nickname (String), location (FFGeoLocation) and profilePic (byte[]). The FFUser class can be easily extended to include whatever you want, see the examples below:
[tabs_framed] [tab title="Android"]

public class MyFFUser  extends FFUser {
private String m_nickname;
private FFGeoLocation m_home;
private byte[] m_profilePic;

public String getNickname() { return m_nickname; }
public FFGeoLocation getHome() { return m_home; }
public byte[] getProfilePic() { return m_profilePic; }

public void setNickname(String nickname) { m_nickname = nickname; }
public void setHome(FFGeoLocation home) { m_home = home; }
public void setProfilePic(byte[] profilePic) { m_profilePic = profilePic; }
}
// Then just make sure and let the SDK know you want to use this class instead of FFUser
FFObjectMapper.registerClassNameForClazz(MyFFUser.class.getName(), "FFUser");

You can see the full source for subclassing FFUser for Android on GitHub here
[/tab] [tab title="iOS"]
@interface MyFFUser : FFUser

@property (strong, nonatomic) NSData *profilePic;
@property (strong, nonatomic) FFGeoLocation *home;
@property (strong, nonatomic) NSString *nickname;

@end
// Then just make sure and let the SDK know you want to use this class instead of FFUser
[ff registerClass:[MyFFUser class] forClazz:@"FFUser"];

You can see the full source for subclassing FFUser for iOS on GitHub here[/tab] [tab title="HTML5/JS"]
function MyFFUser() {
this.clazz = "MyFFUser";
this.FFUser = FFUser;
this.FFUser();
this.userName = null;
this.firstName = null;
this.lastName = null;
this.email = null;
this.active = null;
this.profilePic = null;
this.home = new FFGeoLocation();
}
MyFFUser.prototype = new FFUser;
You can see the full source for subclassing FFUser for HTML5/JS on GitHub here
[/tab] [/tabs_framed]

FFDL definition for FFUser to use MyFFUser additional parameters

CREATE OBJECTTYPE FFUser (userName STRING, firstName STRING, lastName STRING, email STRING, active BOOLEAN, authDomain STRING, scriptAuthService STRING, groups GRABBAG /FFUserGroup, notif_ids GRABBAG /FFNotificationID, profilePic BYTEARRAY, nickname STRING, home GEOLOCATION)
The FFDL definition for FFUser source on GitHub can be found here

Test cases for registering a MyFFUser user

For brevity, I will not include the code for the test cases that will verify that registering a user works properly using the subclass of FFUser. Instead, I will include the links below:
Android test case for registering a MyFFUser user
iOS test case for registering a MyFFUser user
HTML5/JS test case for registering a MyFFUser user

Method 2: PublicProfile class with a REFERENCE to FFUser(MyFFUser)

The second method is to add the additional information to a new Objecttype (my example is called PublicProfile) that contains the same additional information, but also includes a REFERENCE to FFUser. This allows for managing access control for some user information independent of the FFUser which may be useful in some cases. Note – for this exercise, the FFUser still has the expanded parameters, but the sample code only populates the standard info for a user. They point is that you can easily separate what is private and what is more “public”.
[tabs_framed] [tab title="Android"]

public class PublicProfile {
private MyFFUser m_user;
private byte[] m_profilePic;
private String m_nickname;
private FFGeoLocation m_home;

public MyFFUser getUser() { return m_user; }
public String getNickname() { return m_nickname; }
public FFGeoLocation getHome() { return m_home; }
public byte[] getProfilePic() { return m_profilePic; }

public void setUser(MyFFUser user) { m_user = user; }
public void setNickname(String nickname) { m_nickname = nickname; }
public void setHome(FFGeoLocation home) { m_home = home; }
public void setProfilePic(byte[] profilePic) { m_profilePic = profilePic; }
}

You can see the full source for the PublicProfile class for Android on GitHub PublicProfile class with REFERENCE for Android
[/tab] [tab title="iOS"]
@interface PublicProfile : NSObject

@property (strong, nonatomic) MyFFUser *user;
@property (strong, nonatomic) NSData *profilePic;
@property (strong, nonatomic) NSString *nickname;
@property (strong, nonatomic) FFGeoLocation *home;

@end

You can see the full source for the PublicProfile class for iOS on GitHub PublicProfile class with REFERENCE for iOS
[/tab] [tab title="HTML5/JS"]
function PublicProfile(obj) {
if(obj) {
this.user = new MyFFUser(obj.user);
this.profilePic = obj.profilePic;
this.nickname = obj.nickname;
this.home = new FFGeoLocation(obj.home);
} else {
this.user = new MyFFUser();
this.profilePic = null;
this.nickname = null;
this.home = new FFGeoLocation();
}
}
PublicProfile class with REFERENCE for HTML5/JS
[/tab] [/tabs_framed]

FFDL definition for PublicProfile with REFERENCE to MyFFUser(FFUser)

#Objecttype definition
CREATE OBJECTTYPE PublicProfile (user REFERENCE /FFUser, profilePic BYTEARRAY, home GEOLOCATION, nickname STRING)
# Permission setting
CREATE COLLECTION /FFUser OBJECTTYPE FFUser
#PERMIT read:system.admins write:system.admins ON /FFUser
CREATE COLLECTION /PublicProfiles OBJECTTYPE PublicProfile
#PERMIT read:loggedin write:system.admins ON /PublicProfile
You can find the FFDL definition for PublicProfile on GitHub here

Test cases for registering a FFUser(MyFFUser) user and creating a PublicProfile

For brevity, I will not include the code for the test cases that will verify that registering a user and creating a profile object works properly. Instead, I will include the links below:
Android test case for registering a FFUser(MyFFUser) user and creating a PublicProfile as well
iOS test case for registering a FFUser(MyFFUser) user and creating a PublicProfile as well
HTML5/JS test case for registering a FFUser(MyFFUser) user and creating a PublicProfile as well

Hope that you find this useful…

Kevin

FYI – Having fun with datagraphs

So most of our sample code on GitHub is a result of a developer’s question that we think has general interest that other developers may find useful. This usually ends up also being a small sample application that will show the result in a simple UI.

But, sometimes we do things just for fun. For today’s example, I decided to code up the excellent descriptions on the NoServer features page

You can access the source code for the sample application here.
You can access the sample application – complete with data, images and all here.

It is interesting that now that it is so easy to create an app with a backend, that one can create the code (couple of hours), wrap it in an app (less than a couple of hours) and then blog about it.

So what this app does:

This application uses a single Objecttype (Person) and a single Collection (Persons) to demonstrate just how powerful a datagraph representation can be, and how super efficient queries can be constructed to “walk” your datagraph to get what you want with a single call in your client.

The FFDL

First, defining the backend in FFDL takes only two lines of code!

CREATE OBJECTTYPE Person (firstName STRING, lastName STRING, gender STRING, mother REFERENCE /Persons, father REFERENCE /Persons, siblings GRABBAG /Persons, picture BYTEARRAY)
CREATE COLLECTION /Persons OBJECTTYPE Person

The REFERENCE associations above (mother and father), these can be considered “one to one” relationships between person objects.

The GRABBAG association (siblings) are essentially “one to many” relationships between person objects.

The system also creates reverse relationships for all of these automatically called BackReferences that provides an extremely powerful means of “walking” your datagraph.

References

The first example shows how to retrieve an object using a REFERENCE. We first get the Person with firstName “Bart” and then get the Person referenced by the object member “father”.

var bart, homer;
ff.getObjFromUri("/Persons/(firstName eq 'Bart')/father", function(response) {
homer = response;
});
//or, if bart has already been loaded on the client
homer = bart.father;
You can see References working here.

Grab Bags

This next example shows how to retrieve a set of objects from a Grab Bag by reference. We want to get all of Bart’s aunts on his mother’s side. To do this, we will first get the Person with firstName “Bart”, then get Marge from the “mother” member Reference, then get siblings from the Grab Bag referenced by the object member “siblings”.

var grabbags;
ff.getArrayFromUri("/Persons/(firstName eq 'Bart')/mother/()/siblings/(gender eq 'Female')", function(response) {
grabbags = response;
});
You can see Grab Bags working here.

Back References

This next example shows how to retrieve objects using Back References. There are three tests here – the first gets all BackReferences to “homer”. The second gets all the Person objects from the Grab Back that reference homer by the “siblings” Reference member. The third gets all the Person objects that refer to homer by the “father” Reference member.

var homer, allBackRefs;
ff.grabBagGetAll(homer, "BackReferences", function(response) {
allBackRefs = response;
});
var homer, allSiblingBackRefs;
ff.grabBagGetAll(homer, "BackReferences.Persons.siblings", function(response) {
allSiblingBackRefs = response;
});
var homer, allFatherBackRefs;
ff.grabBagGetAll(homer, "BackReferences.Persons.father", function(response) {
allFatherBackRefs = response;
});
You can see BackReferences working here.

Queries

This last example shows how to retrieve objects using some more advanced queries. There are five examples in this section. The first example will get all the Person objects that have a “father” Reference member (Note that the returned values are deduplicated). The second is basically the same, but uses the “mother” Reference member. The third example shows the use of a logical OR to get all of Bart’s granparents. The fourth example is similar, but adds another logical OR to get all of Bart’s grandparents. The last shows a complex query to get all of Ling’s cousins (the team’s favorite query).

var fathers;
ff.getArrayFromUri("/Persons/()/father"), function(response) {
fathers = response;
});
var mothers;
ff.getArrayFromUri("/Persons/()/mother"), function(response) {
mothers = response;
});
var grandfathers;
ff.getArrayFromUri("/Persons/(firstName eq 'Bart')/father or mother/()/father"), function(response) {
grandfathers = response;
});
var grandparents;
ff.getArrayFromUri("/Persons/(firstName eq 'Bart')/father or mother/()/mother or father"), function(response) {
grandparents = response;
});
var cousins;
ff.getArrayFromUri("/Persons/(firstName eq 'Ling')/father or mother/()/siblings/()/BackReferences.Persons.mother or BackReferences.Persons.father"), function(response) {
cousins = response;
});
You can see Queries working here.

Get the Entire Datagraph

Lastly, you can actually retrieve the entire datagraph in a single query by specifying the “depth” of the leaf-level items returned. This test will fetch the entire datagraph.

var datagraph;
ff.getArrayFromUri("/Persons/()?depthRef=3&depthGb=3", function(response) {
datagraph = response;
});
You can see the entire Datagraph here.

Final note: the source code includes a couple of Server Extensions that are used to populate/unpopulate the data for this app. You may find these useful samples, although they are rather brute force and inelegant in their current form.

FYI – FatFractal Makes File Upload Easy

You can access the source code for the sample application here.

Inspired by a recent blog post by Raymond Camden, we decided to show how much easier FatFractal makes it to create an object containing a blob. This example uses our JavaScript SDK in a PhoneGap app, but all of our SDKs feature the same ease of use.

Here’s the relevant code for uploading with FatFractal:

// Not even a little bit complex -- just set the member
var newNote = {
clazz: "Note",
text: noteText
};
if (imagedata) newNote.picture = imagedata;

ff.createObjAtUri(newNote, "/Note", function(result) {
$.mobile.changePage("#home");
}, function(error) {
console.log("Oh crap", error);
});
cleanUp();

Here’s the Parse code (from Raymond Camden’s blog):

/*
A bit complex - we have to handle an optional pic save
*/
if (imagedata != "") {
var parseFile = new Parse.File("mypic.jpg", {base64:imagedata});
console.log(parseFile);
parseFile.save().then(function() {
var note = new NoteOb();
note.set("text",noteText);
note.set("picture",parseFile);
note.save(null, {
success:function(ob) {
$.mobile.changePage("#home");
}, error:function(e) {
console.log("Oh crap", e);
}
});
cleanUp();
}, function(error) {
console.log("Error");
console.log(error);
});

} else {
var note = new NoteOb();
note.set("text",noteText);
note.save(null, {
success:function(ob) {
$.mobile.changePage("#home");
}, error:function(e) {
console.log("Oh crap", e);
}
});
cleanUp();
}

(The only other significant change was to switch to reading the image from the filesystem rather than receive it as a base64-encoded string, which is arguably better practice anyway. Check out the full source up on GitHub!)

So, instead of forcing you to create and save a special file object, FatFractal lets you do the natural thing: you set the member, we take care of the rest.

FYI – FatFractal now provides textual term search for NoServer apps!


As a developer, I want to be able to retrieve information from my backend using search technology so that I can create even more powerful queries and get super fast responses.

You can see working code for everything below (here).
You can access the source code for the sample application (here).

We are really excited to announce that we our latest release includes full textual term search for all your data that is stored on FatFractal NoServer applications. This opens up an entirely new set of options for your queries and they are super fast to boot!

How it works:

We have recently started to use elasticsearch – a superb product by the way, and a future post will outline why we switched to it – as one of the data stores for your app’s data. Basically, as before, everything that is stored is fully indexed for you automatically without any configuration of your application or schema required. In addition, our implementation does not impose any additional overhead on any interaction with your data (Create, Read Update or Delete), but it has vastly improved the response times for all queries and we have added full textual term search as well.

How to use it:

We have added two new operators that you can use in your queries, “contains_all” and “contains_any”. These provide textual term search capability for queries that looks for, you guessed it, ANY submitted term matches or ALL submitted terms match.
For more information, you can find the documentation for the FatFractal Query Language (here).

Examples:

As usual, we have created a sample application to illustrate this, you can try the application (here), and the source code for the application is (here) and also play with the databrowser for the application’ backend (here).

The sample application uses a Movies collection that holds Movie objects. The movie objects have a member called “description” which we will be searching.

The model for Movie is as follows:

function Movie() {
this.title = null;
this.description = null;
this.year = null;
return this;
}
We have populated the collection with two Movies as shown below:

{
"title": "The Conjuring",
"description": "Paranormal investigators Ed and Lorraine Warren work to help a family terrorized by a dark presence in their farmhouse. Forced to confront a powerful entity, the Warrens find themselves caught in the most terrifying case of their lives.",
"year": 2013
},
{
"title": "Grown Ups 2",
"description": "After moving his family back to his hometown to be with his friends and their kids, Lenny finds out that between old bullies, new bullies, schizo bus drivers, drunk cops on skis, and 400 costumed party crashers sometimes crazy follows you.",
"year": 2013
}
So, now let’s create a couple of queries that use free text search.

Search using contains_any

First, we will search the Movies collection for any Movie objects whose description member contain any one of two terms (for example, “family” and “terrorized”). The query looks like this:

/Movies/(description contains_any 'family terrorized')
The code looks like this:
function searchAny() {
var eli = document.getElementById('movies-search-any-input');
ff.getArrayFromUri("/ff/resources/Movies/(description contains_any '" + eli.value + "')", function(movies) {
// handle success
}, function(code, msg) {
// handle error
});
}
Since “family” is contained in both “The Conjuring” as well as “Grown Ups 2” descriptions, this query will return both objects.

Search using contains_all

Next, let’s use the same search terms, but use the contains_all operator, which will search for any Movie objects whose description member contain both search terms.

/Movies/(description contains_all 'family terrorized')
The code looks like this:
function searchAll() {
var eli = document.getElementById('movies-search-all-input');
ff.getArrayFromUri("/ff/resources/Movies/(description contains_all '" + eli.value + "')", function(movies) {
// handle success
}, function(code, msg) {
// handle error
});
}
In this case, the query will return only “The Conjuring” as it’s descrption contains both terms and “Grown Ups 2” does not.

As mentioned above, these operations are extremely fast and efficient as any data that is stored on your backend is fully indexed automatically as soon as it is created or modified.

Have fun!

Kevin

FYI – FatFractal improves authentication support with full OAuth 1.0 and OAuth 2.0 support


User authentication is an ages old problem for developers that has greatly improved recently thanks to the emergence of trusted providers such as Twitter and Facebook.

FatFractal has provided integrated authentication with Facebook and Twitter on the client-side for some time. We have just released a major upgrade to our backend support for full OAuth 2.0 as well as OAuth 1.0 using the Scribe library.

Implementing single-sign-on using a trusted provider like Facebook or Twitter makes a lot of sense. Now, implementing this has gotten a lot easier. The basic steps to using either as an authentication provider with FatFractal are:

  1. Register your application with the provider
  2. Add the keys from one or both to the Auth.js file that is created during application scaffolding
  3. Implement the auth life-cycle in your application

Full documentation for the FatFractal ScriptAuth process is found here

You can see working code for everything below (here).

First, you need to add the application keys for Twitter and/ or Facebook into the Auth.js file that is automatically created for you when you scaffold your application with FatFractal. The Auth.js code looks like this:

auth.setScribeApiClassName(TWITTER, "org.scribe.builder.api.TwitterApi");
auth.setScribeApiKey(TWITTER, "twitter_api_key");
auth.setScribeApiSecret(TWITTER, "twitter_api_secret");

auth.setScribeApiClassName(FACEBOOK, "org.scribe.builder.api.FacebookApi");
auth.setScribeApiKey(FACEBOOK, "facebook_app_id");
auth.setScribeApiSecret(FACEBOOK, "facebook_app_secret");

You need to replace the ApiKey and ApiSecret values with the corresponding values for Facebook and/ or Twitter. Then, the basic components needed for the sample app above are (in HTML/Javascript) are quite straightforward:

  1. Create a login for Facebook function
  2. Create a login for Twitter function
  3. Create a page that will handle process the callback from the provider and redirect back the application page with the user logged in

Next, we set up the callback URI that both will use (you could also create separate pages fors handling Facebook or Twitter if you prefer).

var callbackUri = ff.getBaseUrl() + "authorize.html";
sessionStorage.setItem("ff-callback-uri", callbackUri);
ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, callbackUri);
ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, callbackUri);
Note that we are saving the callback in sessionStorage as we will want to use that later from the authentication page.

Here is the code for launching the Facebook login process:

// Facebook login
function facebookLogin() {
ff.authUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK,
function(authUri) {
sessionStorage.setItem("ff-auth-provider", "FACEBOOK");
window.location = authUri;
}, function(code, msg) {
console.error("facebookLogin() Error: " + code + " " + msg);
});
}

And, here is the code for launching the Twitter login process:

// Twitter login
function facebookLogin() {
ff.authUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, function(authUri) {
sessionStorage.setItem("ff-auth-provider", "FACEBOOK");
window.location = authUri;
}, function(code, msg) {
console.error("facebookLogin() Error: " + code + " " + msg);
});
}
Note that we are also saving the authentication provider in sessionStorage as well in order to have a single page to handle the response.

var callbackUri = sessionStorage.getItem("ff-callback-uri");
var provider = sessionStorage.getItem("ff-auth-provider");
var ff = new FatFractal();
if(provider == "FACEBOOK") {
ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, callbackUri);
ff.retrieveAccessTokenForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, location.href, function() {
ff.loginWithScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, function(user) {
var msg = "Success! Logged in as " + user.guid;
var el = document.getElementById('status');
el.innerHTML = "<br><div class = 'well'>Logged in with Facebook - message: " + msg + "</div>";
window.location = "index.html";
});
});
} else if(provider == "TWITTER") {
var requestToken = JSON.parse(sessionStorage.getItem("ff-tw-request-token"));
sessionStorage.removeItem("ff-tw-request-token");
ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, callbackUri);
ff.setRequestTokenForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, requestToken);
ff.retrieveAccessTokenForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER,
location.href, function() {
ff.loginWithScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, function(user) {
var msg = "Success! Logged in as " + user.guid;
var el = document.getElementById('status');
el.innerHTML = "<br><div class = 'well'>Logged in with Twitter - message: " + msg + "</div>";
window.location = "index.html";
});
});
} else console.error("Could not determine the OAuth provider");
When the callback is received, this page will complete the authentication process, create the logged in user and session and redirect back the original page logged in.

That’s it,

Kevin

FYI – Datagraph with Objects and Collections


As a developer, I want to have complete control of my objects and collections on the backend.

There are so many terms being thrown around these days that it is often difficult to separate the truth from the marketing hype. So – at FatFractal, when we talk about our Datagraph capabilities, we mean a real graph, not marketing hype. To illustrate, let me show you a couple of simple examples.

You can see working code for everything below (here).
You can access the source code for the sample application (here).

Most of the time, you will define an object and map it to a identical collection.

Let’s start with couple of simple object definitions:

function Movie() {
this.title = null;
this.description = null;
this.year = null;
}
function Actor() {
this.firstName = null;
this.lastName = null;
}

Then, we add the following to our FFDL (what’s this?), to define these object types and collections on the backend as follows:

CREATE OBJECTTYPE Movie (title STRING, description STRING, year NUMERIC)
CREATE OBJECTTYPE Actor (firstName STRING, lastName STRING)
CREATE COLLECTION /Movies OBJECTTYPE Movie
CREATE COLLECTION /Actors OBJECTTYPE Actor

Note – that the two collections are typed to an object type (Movie and Actor), which means that attempting to store a Movie in the Actors collection or vice-a-versa will generate a validation error.

But, let’s say that you want to create a collection of favorites and allow it to hold different object types, while also still being able to distinguish them from each other. No problem, to do that, let’s add a new collection called Favs that is not typed:

CREATE COLLECTION /Favs OBJECTTYPE *

Examples:

First, let’s store an object in a collection typed to a Movie object type:

var m = new Movie();
m.title = "Argo";
m.description = "Argo is a 2012 historical drama thriller film directed by Ben Affleck.";
m.year = 2012;
ff.createObjAtUri(m, "/Movies");

Now – let’s try saving a Movie to the Favs collection…

ff.createObjAtUri(m, "/Favs");

Similarly, you can store an Actor in the Actors collection or in the Favs collection…

var a = new Actor();
a.firstName = "Ben";
a.lastName = "Affleck"
FatFractal.createObjAtUri(a, "/Actors");
FatFractal.createObjAtUri(a, "/Favs");

But, if you try to store a Movie in the Actors (or vice-a-versa) collection, you will get an error…

FatFractal.createObjAtUri(m, "/Actors");

Now – let’s see how you can retrieve objects of a particular class from a collection that holds more than one object type.

Get all the Movie objects from the Favs collection…

ff.getArrayFromUri("/ff/resources/Favs/(clazz eq 'Movie')", function(r) {
// handle success
}, function(code,message){
// handle error
});

Get all the Actor objects from the Favs collection…

ff.getArrayFromUri("/ff/resources/Favs/(clazz eq 'Actor')", function(r) {
// handle success
}, function(code, message){
// handle error
});

Get all the objects from the Favs collection…

ff.getArrayFromUri("/ff/resources/Favs/", function(r) {
// handle success
}, function(code, message){
// handle error
});

That’s it – we hope that you will agree that this is another example of FatFractal being the most flexible, robust and capable backend for your app – enjoy!

Kevin

FYI – Retrieve an object graph in a single query with FatFractal


As a developer, I want an easy to navigate data model (a datagraph) so that I can get the data I want with fewer API calls which increases my applications performance and saves me money.

We have added a new capability that allows you to retrieve an object graph (the object as well as all of its REFERENCES and GRABBAGS) in a single API call. This can improve the the performance of your application and reduce the “chattiness” of using your API.

Previously, you could retrieve an object from a URI such as:

http://telluride.fatfractal.com/tff39/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4

For which you would get a response like this…[toggle title="Click to see response"]

{
"result":
[
{
"ffUserCanEdit": false,
"ffUrl": "/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4",
"qa": false,
"ffRL": "/Showings",
"updatedBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"version": 1,
"updatedAt": 1346642155713,
"guid": "e-06R5_d_FfHXKHSCx-ky4",
"ffRefs":
[
{
"name": "theater",
"type": "FFO",
"url": "/ff/resources/Theaters/h3uX2Gt1j74w4yYbcifNq6"
},
{
"name": "film",
"type": "FFO",
"url": "/ff/resources/Films/KG09l8GvwRc9pUzXGMTEJ4"
}
],
"createdBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"createdAt": 1346642155713,
"datetime": 1315094400000,
"clazz": "Showing"
}
],
"statusMessage":"Retrieved 1 resources from /ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4"
}
[/toggle] The response includes the object itself (in ‘result’), and includes the URIs for any references (in this case, there are two). The FatFractal SDKs would then retrieve the referenced objects (requires a minimum of two additional queries, plus even more if these objects contain references or grabbag items themselves). That makes for a lot of round trips for the queries which can be expensive and adversely impact your application performance.

Get More for Less

Now you can access the entire datagraph from the object instance at a specified depth by adding the depthRef (depth for references) and depthGb (depth for grabbags) parameters:

http://telluride.fatfractal.com/tff39/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4?depthRef=1&depthGb=1

This will return the object AND all of the object’s REFERENCES and GRABBAGS that the user has permission to read in a single response.

The response will now look like this…[toggle title="Click to see response"]

    "result":
[
{
"ffUserCanEdit": false,
"ffUrl": "/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4",
"qa": false,
"ffRL": "/Showings",
"updatedBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"version": 1,
"updatedAt": 1346642155713,
"guid": "e-06R5_d_FfHXKHSCx-ky4",
"ffRefs":
[
{
"name": "theater",
"type": "FFO",
"url": "/ff/resources/Theaters/h3uX2Gt1j74w4yYbcifNq6"
},
{
"name": "film",
"type": "FFO",
"url": "/ff/resources/Films/KG09l8GvwRc9pUzXGMTEJ4"
}
],
"createdBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"createdAt": 1346642155713,
"datetime": 1315094400000,
"clazz": "Showing"
}
],
"references":
[
{
"ffUserCanEdit": false,
"filmType": 0,
"ffUrl": "/ff/resources/Films/KG09l8GvwRc9pUzXGMTEJ4",
"director": "Ben Affleck",
"ffRL": "/Films",
"country": "U.S.",
"version": 1,
"updatedBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"guid": "KG09l8GvwRc9pUzXGMTEJ4",
"updatedAt": 1346472626252,
"filmDescription": "While 50 Americans are held hostage by the Ayatollah Khomeini’s Revolutionary Guard, six U.S. Embassy employees hiding at the Canadian ambassador’s residence in Teheran stage a daring escape. “Extraction” expert Tony Mendez (Ben Affleck) enlists a veteran Hollywood make-up expert and producer (John Goodman and Alan Arkin, each giving disciplined comic performances) to create a sham sci-fi movie epic in the hopes of finding a way out of the country. Affleck directs with formidable precision and documentary-style immediacy, intercutting between turf battles between the CIA and Washington diplomats, the chaotic street violence during Iran’s revolution and the black comedy of spies pretending to be Hollywood types. This is thrilling, nail-biting entertainment.nIn person: Ben Affleck",
"duration": 120,
"title": " SNEAK: Argo",
"ffRefs": [],
"createdBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"createdAt": 1346472626252,
"madePossibleBy": "",
"year": 2012,
"actors": "",
"clazz": "Film"
},
{
"ffUserCanEdit": false,
"ffUrl": "/ff/resources/Theaters/h3uX2Gt1j74w4yYbcifNq6",
"ffRL": "/Theaters",
"version": 1,
"updatedBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"guid": "h3uX2Gt1j74w4yYbcifNq6",
"updatedAt": 1346359016787,
"createdBy": "Os0t9Mjm7FhPemzN0uQ8U7",
"address": "",
"createdAt": 1346359016787,
"name": "Chuck Jones Cinema",
"capacity": 500,
"longitude": -107.8478,
"latitude": 37.9361,
"sponsorString": "",
"shortName": "Chuck Jones",
"clazz": "Theater"
}
],
"statusMessage":"Retrieved 1 resources from /ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4"
}
[/toggle]

As you can see, the response includes the object itself (in ‘result’), but additionally, all objects referenced or contained in grabbags have been retrieved as well.

In your client code, using the methods provided in the various SDKs, the REFERENCE and GRABBAG items are automatically incorporated into your client object model, but now these are populated with a single request.

For more info on references, see the docs here.

Have fun!

Kevin

Contact