Create google app engine console project Sign up for Google App Engine: https://console developers google com/project


Download 76.48 Kb.
NameCreate google app engine console project Sign up for Google App Engine: https://console developers google com/project
A typeDocumentation



Google App Engine Java

To Use google app engine either with Android or IOS

Create google app engine console project

  • Sign up for Google App Engine: https://console.developers.google.com/project

  • Create new application

create Your application in Eclipse

  • Install GAEJ(Google App Engine java) Plug-in:


From eclipse . Help  Install new software  (http://dl.google.com/eclipse/plugin/3.X) X depends on your version of eclipse

  • Create first GAEJ application

(we intersted in connected android):

File –> New –> Other –> App Engine Connected Android Project

  • This step can be found in details in this link https://developers.google.com/eclipse/docs/endpoints-androidconnected-gae

Now you have 2 applications created, one web application (App engine) and Android application.

Web application:


You will find an auto generated class “EMF.java” → Entity Manager Factory

This is the handle on the database , we use it to run queries . Here is where we set some parameters to use authentication (As we will show later).


@Entity // before the declaration of the class

@Id // before the field representing the primary key

@GeneratedValue (strategy=GenerationType.IDENTITY) // before the field representing the primary key to make it auto generated

Create Model Classes with :


Create EndPoints (class where you write queries):




    • App Engine can automatically create the basic queries (select – insert – update - delete) for each Model class, and place it in a class called Endpoint which are used later to create library to be used in android application.

    • To create endpoint right click target class --> google --> "generate cloud endpoint class".

    • A class named “[Class name] Endpoint” is created now.



    • This Class contains functions:

      • list [Class name]  Select

      • get [Class name]  get by ID

      • Insert [Class name]  Insert

      • update [Class name]  update

      • remove [Class name]  Delete



    • You can add new Method that calls your own query , but there are annotations that u should put for app engine to understand that this method is to be called from android app.(You can copy one of the generated methods and update its name )

Tips for writing methods and queries :




      • cannot use greater than ”>” and less than “<” in single query on different fields

      • Return type must be serializbale object.

      • cannot use two equality operators on different fields without indexing to do so go to:

war--> web-info --> appengine-generated -->datastore-indexes-auto.xml


"Images
" ancestor="false" source="manual">




Follow this example: replacing with the entity name that u want to query, and its properties (fields).


Create servlets


You can create servlets to apply any logic on the back end (App engine). You can also use servlets to insert testing data .After creating servlet we should do servlet mapping so we can call this servlet from browser.




servlettest
// Servlet name

com.innovationwaves.inshop.servletTest // class name





servlettest //Servlet name

/servlettest // the name you want to use it to call the servlet



Go to War  Web-Inf  web.xml

Deploy:




  1. To deploy: use the ID of the console project created in the first step  right click  properties  google  appengine  enter project id

  2. Right click  google  deploy


Rollback


rollback cmd


eclipse/plugins/com.google.appengine.eclipse.sdkbundle_X.X.X/appengine-java-sdk-X.X.X/bin/appcfg.sh --email=XXXX@innovation-waves.com rollback /Users/XXXXXXX/Documents/workspace/AppEngineApp/war

replace x.x.x with the version of appengine that you are deploying with.

If this failed try this

  1. open command prompt (cmd.exe) in D:\Java\eclipse\plugins\com.google.appengine.eclipse.sdkbundle_1.8.3\appengine-java-sdk-1.8.3\bin> (or look for the location of your appcfg.cmd somewhere else)

  2. type in: appcfg.cmd --oauth2 rollback D:/Java/workspace/my_app/war

  3. Then I was prompted with oauth2 token in my browser , did copy and got back to the cmd than paste

  4. That's it! Deploy to App Engine works again!


Relations

Many to Many relation:

How to create


Example: we have 2 tables “Menu Items”, “Ingredient”

We will create a new table” Menu Ingredient “ (Many to many expansion table)

Menu Item” Table:

@Entity

public class MenuItem {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Key id;

private String name;

public Key getId() {

return id;

}

public void setId(Key id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

Ingredient” Table:

@Entity

public class Ingredient {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Key id;

private String name;

public Key getId() {

return id;

}

public void setId(Key id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}


Note that: we have to add for each foreign key annotations @Persistent(defaultFetchGroup="true")

@Unowned
Menu Ingredient” Table:

@Entity

public class MenuIngredient {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Key id;


Foreign key of table

“Menu Item”


@Persistent(defaultFetchGroup="true")

@Unowned

MenuItem menuitem=new MenuItem();


Foreign key of table

“Ingredients”


@Persistent(defaultFetchGroup="true")

@Unowned

Ingredient ingredient ;

public Key getId() {

return id;

}

public void setId(Key id) {

this.id = id;

}

public MenuItem getMenuitem() {

return menuitem;

}

public void setMenuitem(MenuItem menuitem) {

this.menuitem = menuitem;

}

public Ingredient getIngredient() {

return ingredient;

}

public void setIngredient(Ingredient ingredient) {

this.ingredient = ingredient;

}

}


Eager fetch problem:


As for this relation to work we have to use eager fetch (the app engine insist to fetch all the relation data including its children) and this causes an undetached field’s problem.

  • To solve this Apply the highlighted code to your endpoint while querying the data:

@ApiMethod(name = "listMenuIngredient")

public CollectionResponse listMenuIngredient(

@Nullable @Named("cursor") String cursorString,

@Nullable @Named("limit") Integer limit) {

EntityManager mgr = null;

List execute = null;

List result = new ArrayList();

try {

mgr = getEntityManager();

Query query = mgr

createQuery("select from MenuIngredient as MenuIngredient");

execute = (List) query.getResultList();

for (MenuIngredient obj : execute)

{

//To avoid crash because of undetached fields

MenuIngredient mi=new MenuIngredient();

mi.setId(obj.getId());

mi.setIngredient(obj.getIngredient()); // here u can fetch one entity only

result.add(mi);

}

} finally {mgr.close();}

return CollectionResponse. builder().setItems(result).setNextPageToken(cursorString).build();

}

Tip for using unowned relationship:


need to modify the EMF:

public static EntityManagerFactory get() {

if(emfInstance==null){

Map props = new HashMap<>();

props.put("datanucleus.appengine.datastoreEnableXGTransactions",Boolean.TRUE.toString());

emfInstance = Persistence.createEntityManagerFactory("transactions-optional", props);

}

return emfInstance;

One to many Relation

How to create


Example: we have 2 tables “Employee”, “Department”

(Each department has many employees but each employee can work in only one department.)

We will Add List of employees (Objects) in the department entity

Employee Table:

@Entity

public class Employee {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Key id;

private String name;

public Key getId() {

return id;

}

public void setId(Key id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

Department Table:

@Entity

public class Department {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Key id;

private String name;

@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)

private List employees=new ArrayList();

public Key getId() {

return id;

}

public void setId(Key id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public List getEmployees() {

return employees;

}

public void setEmployees(List employees) {

this.employees = employees;

}

}

Insert query


To insert Object you have to insert from parent

Employee e=new Employee();

e.setName("Mostafa");

Department dep=new Department();

dep.setName("Dept1");

dep.getEmployees().add(e);

EntityManager emf=EMF.get().createEntityManager();

emf.persist(dep);

emf.close();

Update query


using auto generated endpoints to update object won't work cause u will have separate entity managers for the select and the update so you have to write both in one new API method. The select (not including fetch) then the update the fields of the object from the parameter (will replace the database object with the one in parameter so u have to make sure that the parameter include all the needed data not only the new ones.) then merge.

Authentication

Get google account credential.


Code that silently extracts all google accounts silently and picks one of them and uses it to authenticate the user and the application at the same time (the web id is bound to an android client id which has the SHA1 thumbprint of the application signing certificate).

googleAccountCredential=GoogleAccountCredential.usingAudience(RegisterActivity.this,"server:client_id: 820217714652-i8lsj0m5f5hsd360f0le3q1lcl2qfl4g.apps.googleusercontent.com");//use the web id

public static GoogleAccountCredential getGoogleAccountCredential(Context con)

{

GoogleAccountCredential googleAccountCredential = GoogleAccountCredential.usingAudience(con, "server:client_id:" + WEB_ID);

// Get From settings

String userAccount = "";

// if not in setting

if (userAccount.length() == 0)

{

AccountManager accountManager = AccountManager.get(con);

Account[] accounts = accountManager.getAccountsByType("com.google");

// String accountName = "";

for (Account account : accounts)

{

userAccount = account.name;

break;

}

}

googleAccountCredential.setSelectedAccountName(userAccount);

return googleAccountCredential;

}

Authenticate each endpoint


  • Add whitelisted ids to each endpoint class at the server (in the header of the endpoint)

@Api(name = "deviceinfoendpoint", namespace = @ApiNamespace(ownerDomain = "testdatanucleus.com", ownerName = "testdatanucleus.com", packagePath = ""),

clientIds={"820217714652-jbevt2ql9fump19nprfi7ivdq0vojhgj.apps.googleusercontent.com"/*android client id*/,"820217714652-i8lsj0m5f5hsd360f0le3q1lcl2qfl4g.apps.googleusercontent.com"/*web id*/},

audiences="820217714652-i8lsj0m5f5hsd360f0le3q1lcl2qfl4g.apps.googleusercontent.com"/*web id*/

)

  • Update the endpoint serverside methods to include the User argument, it will be null if authentication is bypassed in any means. (note that if authentication failed, then the client wouldn’t send the request to the server in the first place.)

  • We should use the authenticated email instead of the device id currently in use

  • We should remove all passed device id query parameters and replace it with the identity (email) obtained from the passed User object.

  • We should add an additional field in the user entity that contains a comma separated list of all google emails to facilitate manual account changes support task later on


Caling from android


new AsyncTask() {

@Override

protected Void doInBackground(Void... params) {

// TODO Auto-generated method stub

Employeeendpoint.Builder endpointBuilder = new Employeeendpoint.Builder(

AndroidHttp.newCompatibleTransport(), new JacksonFactory(),

getGoogleAccountCredential(MainActivity.this));

Employeeendpoint endpoint = CloudEndpointUtils.updateBuilder(

endpointBuilder).build();

try {

List el= endpoint.listEmployee().execute().getItems();

for (Employee employee : el) {

Log.d("ddd", employee.getName());

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

}.execute((Void)null);

call from IOS


First you need a tool called "service generator" to convert the service endpoints to be used by Xcode

1- download this tool from svn checkout http://google-api-objectivec client.googlecode.com/svn/trunk/Source/Tools ServiceGenerator-read-only

2- run the service on on rpc or rest and generate files on path you specified

3- pick the generated files and drop it on your xcodeProject

4- from the google-api-objectivec-client-read-only folder pick (OAuth2/HTTPFetcher/GTLCommon_Sources.m/GTLDefines.h/GTLNetworking_Sources.m/JSON/Networking/Objects/Utilities)

Take care of

  • 1-symbol duplicate errors as the files contains imports to .m files remove the import

  • for the picked folders make sure that you removed the projects included

  • add compiler flag for the files as it’s non arc files

  • after these steps if you wanna edit endpoints you’ve to visit steps from num2 and don’t replce files as it

Example of calling with imports

#import "GTLServiceEmployeeendpoint.h"

#import "GTLQueryEmployeeendpoint.h"

static GTLServiceEmployeeendpoint *service = nil;

if (!service) {

service = [[GTLServiceEmployeeendpoint alloc] init];

service.retryEnabled = YES;

//[GTMHTTPFetcher setLoggingEnabled:YES];

}

GTLQueryEmployeeendpoint *query = [GTLQueryEmployeeendpoint queryForListEmployeeWithObject:nil];

[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {

//result

}];

Error handling:


  1. while trying to deploy and find: “AppEngine does not have an application ID

Solution:

Right click project --> properties --> google --> app engine --> application id

  1. change application id takes too much time

Solution:

disconnect internet and reconnect

  1. The App Id you selected, "application id", does not exist”

Solution:

AppEngine is trying to tell you that this application id does not belong to current logged in account (logged in Eclipse)

  1. some times you keep deploy and no change affect the deployed version:

Solution:

check auto build and make sure that console display "Uploading X files.".

  1. After create endpoint :

  • insert not working:

Solution:

Add this check ["ClassObject.getId()!=null &&" ] to the function contains[ClassName](ClassObject)

  • update not working:

Solution:

In the update function at the end change presist to merge

  1. build takes too much time

Solution:

disconnect internet and reconnect

  1. cannot create more than 25 endpoint or when it takes to much time to generate endpoints library

Solution:

merge endpoint into endpoints less than 25

  1. after importing appengine project

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/google/appengine/tools/enhancer/Enhance : Unsupported major.minor version 51.0

Solution:

Right click project --> properties --> java build path → Libraries → select jre system libraries --> click edit → choose jdk 7.

  1. after importing appengine project

JPACursorHelper cannot be resolved

Solution:

1-Right click project --> properties → google → select app Engine → change radio button in using appengine SDK → then ok

2-reverse last step and select the original target -->ok

  1. multiple methods with same rest path

Solution:

add path attribute to api method annotation

  1. -Error: Server Error

Solution:

Check the logs in the console project

  1. Parent keys are immutable

Solution:

cannot use same parent for two records

  1. error in insert relational unowned data

javax.persistence.PersistenceException: Illegal argument at org.datanucleus.api.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException

Solution:

edit EMF.java as mentioned above



  1. Error when trying to use authentication with app engine from android:

java.lang.VerifyError: com/google/api/client/googleapis/extensions/android/gms/auth/GoogleAccountCredential$RequestHandler

Solution:

add google play service Library refrence

  1. error when try to execute network call on main thread:

java.lang.RuntimeException: Unable to start activity ComponentInfo{}: java.lang.IllegalStateException: calling this from your main thread can lead to deadlock

Solution:

start the network call from bg

  1. When app fail to use cloud endpoints

This could be due to many reasons:

  1. Missing Permissions in manifest file

Solution: add these permissions to mainifist

"android.permission.GET_ACCOUNTS" />

"android.permission.USE_CREDENTIALS" />

  1. Error in keystore or Client ID , Web ID used

Solution:

Make sure the Android client ID used have the same SHA1 of the keystore used

  • To get the SHA1 of a keystore (in this example we used the debug keystore Replace by Ur own paths)



C:\> C:\Program Files\Java\jdk1.7.0_25\bin\keytool" -list -v -keystore C:\Users\Eman/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

  1. Missing google-play-service

Solution: Add google-play-service.jar in libs folder or add google-play-service project as library project.


  1. When fail to call API from google API Explorer

Make sure the Annotation for the endpoint method is as follows:

@Api(name = "checkinendpoint", namespace = @ApiNamespace(ownerDomain = "innovationwaves.com", ownerName = "innovationwaves.com", packagePath = "bondera"),

clientIds = {Ids.Android_ID_Release,Ids.Android_ID_Debug, Ids.WEB_ID ,Ids.API_Explorer_Client_ID},

audiences ={ Ids.WEB_ID, Ids.API_Explorer_Client_ID} ,

scopes = {Ids.Scopes}

Where: (Note that u can add client Ids as many as u need[as the keystores used] )

  • Ids.Android_ID_Release: is the Client ID generated using Release Keystore (Brought from the console application)

  • Ids.Android_ID_Debug: is the Client ID generated using Debug Keystore (Brought from the console application)

  • Ids.WEB_ID: is the Web ID (Brought from the console application)

  • Ids.API_Explorer_Client_ID:com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID;

  • Ids.Scopes ="https://www.googleapis.com/auth/userinfo.email";

Referances:

http://gaejexperiments.files.wordpress.com/2010/03/gaejexperiments.pdf

https://developers.google.com/appengine/docs/java/

Share in:

Related:

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconIndex Terms Google App Engine; Cloud Computing;PaaS, Karwendel

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconAbstract : a local business listing in Google Maps can be created...

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project icon# 顺便提供能够解析出 Google 的 ipv6 地址的 dns 服务器 ( 因提供这些服务器的 isp 已经加入 Google...

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconGoogle tv project

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconAndroid App Development Course using Google’s Latest ide “Android Studio”

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconPublic domain material from the Google Print project

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconTo create a project and add a source file in C++ Win32 Console Projects

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project icon2012 Create Your Google Account

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconIs the app name that appears to users. For this project, use "My First App."

Create google app engine console project Sign up for Google App Engine: https://console developers google com/project iconWalkthrough: Deploying a SignalR autohosted App to Office 365 Written...




forms and shapes


When copying material provide a link © 2017
contacts
filling-form.info
search