Backendless Support
 

Loading data objects belonged to the logged in user (Owner Policy)

Backendless Platform handles perfectly the problem of loading only the data that belongs to the currently logged - in user. 

Before getting to the coding sample part it is worth reviewing the following Backendless issues:  

Loading data objects which belong to a user does not require any specialized APIs.

In fact, in this case a developer should use exactly the same Backendless API which is used to load objects from the server. The trick is in setting up the security policy to restrict users from accessing data objects and allowing Backendless to fall back to what we call the Owner Policy.

Consider the example below. The code logs in a user and adds a few data objects.

                                           For Objective-C and Swift implementations CLICK HERE

Asynchronous sample (Android and Plain Java):
private static void loginUserAsync()
{
 Backendless.UserService.login( "spidey@backendless.com", "mypassword", new AsyncCallback<BackendlessUser>()
 {
 @Override
 public void handleResponse( BackendlessUser backendlessUser )
 {
 System.out.println( "User has been logged in" ); 
 }
 @Override
 public void handleFault( BackendlessFault backendlessFault )
 {
 System.out.println( "Server reported an error - " + backendlessFault.getMessage() );
 }
 } );
}
private static void addObjectsAsync()
{
 AsyncCallback<Order> callback = new AsyncCallback<Order>()
 {
 @Override
 public void handleResponse( Order order )
 {
 System.out.println( "Order object has been saved - " + order.orderName );
 }
 @Override
 public void handleFault( BackendlessFault backendlessFault )
 {
 System.out.println( "Server reported an error - " + backendlessFault.getMessage() );
 }
 };
 Order order1 = new Order();
 order1.orderName = "spider web";
 order1.orderNumber = 1;
 Backendless.Data.of( Order.class ).save( order1, callback );
 Order order2 = new Order();
 order2.orderName = "costume";
 order2.orderNumber = 2;
 Backendless.Data.of( Order.class ).save( order2, callback );
}
Synchronous sample (Plain Java only):
private static void loginUserSync()
{
 Backendless.UserService.login( "spidey@backendless.com", "mypassword" );
}
private static void addObjectsSync()
{
 Order order1 = new Order();
 order1.orderName = "spider web";
 order1.orderNumber = 1;
 Backendless.Data.of( Order.class ).save( order1 );
 Order order2 = new Order();
 order2.orderName = "costume";
 order2.orderNumber = 2;
 Backendless.Data.of( Order.class ).save( order2 );
}
The Order class which the code above uses is below. The class uses public fields, but could also be turned into a Java Bean with getter and setter methods - Backendless supports either one of the approaches:

Java

package com.mbaas.sample;
public class Order
{
 public String orderName;
 public int orderNumber;
}

Objective-C

#import <Foundation/Foundation.h>
@interfaceOrder:NSObject
@property(nonatomic,strong)NSString *orderName;
@property(nonatomic,strong)NSNumber *orderNumber;
@end

Swift

import Foundation
classOrder:NSObject{
varorderName:String?
varorderNumber:Int=0
}

If a developer hasn't had the Order table in the app and once he/she runs the code, there will be any other Order objects in the table. As a result, to see the effect of loading the objects which belong to the user, it would help to add an additional object belonging to someone else (or no one).

Take a look at the Order table in Backendless console - it contains the ownerId column. That column is automatically added to every table in Backendless. If it contains a value, it will be objectId of the user who created (saved) the object. Add a new row to the Order table using Backendless console and make sure the ownerId column remains empty. The Order table should look like in the screenshot below (the "fish and chips" order was added manually):

 The code to load objects from the Order table is below. Make sure the user is logged in before running the code.

Asynchronous sample (Android and Plain Java):
// make sure the user is logged in. Use the code sample shown above
Backendless.Data.of( Order.class ).find( new AsyncCallback<BackendlessCollection<Order>>()
{
 @Override
 public void handleResponse( BackendlessCollection<Order> users )
 {
 Iterator<Order> userIterator = users.getCurrentPage().iterator();
 while( userIterator.hasNext() )
 {
 Order order = userIterator.next();
 System.out.println( "Order name - " + order.orderName );
 System.out.println( "Order number - " + order.orderNumber );
 System.out.println( "============================" );
 }
 }
 @Override
 public void handleFault( BackendlessFault backendlessFault )
 {
 System.out.println( "Server reported an error - " + backendlessFault.getMessage() );
 }
} );
Synchronous sample (Plain Java only):
// make sure the user is logged in. Use the code sample shown above
BackendlessCollection<Order> orders = Backendless.Data.of( Order.class ).find();
Iterator<Order> userIterator = orders.getCurrentPage().iterator();
while( userIterator.hasNext() )
{
 Order order = userIterator.next();
 System.out.println( "Order name - " + order.orderName );
 System.out.println( "Order number - " + order.orderNumber );
 System.out.println( "============================" );
}

If a developer runs the code before making any changes in the security policy, it will produce the following output: 

Order name - fish and chips
Order number - 3
============================
Order name - consume
Order number - 2
============================
Order name - spider web
Order number - 1
============================

As it is demonstrated, this is not the desired output - the code loads all objects from the table. 

To make the change so the client app gets only the objects which belong to the user, follow the steps below:

  1. Locate the table for which it is necessary to make the restriction in the Data screen of Backendless console. In this case it will be the Order table. Click the Table Schema and Permissions button in the upper right corner.
  2. Click the Roles Permissions menu.
  3. Locate the AuthenticatedUser role and click the cell at the intersection of that role and the Find column until the icon for denying the operation (red X) appears:
  4. Once the change is made, re-run the same code for fetching the data from the table. Now the code returns only the objects which belong to the currently logged in user.
Is article helpful?