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

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

Contact