I'm using Google App Engine and Google Cloud Endpoints to communicate between my Android app (frontend) and the webservice (backend) that runs in the cloud. But I wonder about the URL's used for GET and POST.
Imagine you have a list of notes on the server each with a caption and an id. According to CRUD (create, updated, delete), the HTTP/HTTPS calls should look like that:
Get all notes:
GET http://domain.eu/notes
Get a specific note by it's id (let's say 123):
GET http://domain.eu/notes/id
and so on. But Google uses a different pattern. For instance if you use the API explorer you get calls like this:
GET https://domain/_ah/api/notesEndpoint/v1/notesdata
Question: Is there a general way to get a call for listing all notes? According to the annotations in the source code it should be somewhat like /notes or /notes.listNodes I simply don't understand how Google constructs the URL's
Google Cloud Endpoints use the API-Explorer system.
/_ah/api is defined for the API Explorer, you can't change it.
notesEndpoint is the name of your Api, and v1 the version you define.
notesdata is the name of the method. You can override the path by annotation.
Example, to access to the notes through
domain/_ah/api/notesEndpoint/v1/notes
You have to make this method :
#ApiMethod(
name = "notes.listNodes",
path = "notes",
httpMethod = HttpMethod.GET
)
public List<Foo> notesdata() {
return myList;
}
(a link to the documentation : DOC)
For information, with this system, you can explore your API with this URL :
GET http://domain.eu/_ah/api/explorer
Related
I am trying to implement Android Management API in my project where the first step is to create an enterprise:
Post the Callbackurl and ProjectID to the Following URL
https://androidmanagement.googleapis.com/v1/signupUrls
I get the response name and url:
{
"name": "signupUrls/C265d41bc093bdd97",
"url": "https://play.google.com/work/adminsignup?token=someToken"
}
How can I Change this "url" parameter to my own. Do I require to upload my DPC to playstore?
I am out of guesses. please help
Thanks in advance.
The flow is this:
1) Create a Project in Google developer console, enable Android Management API, create credentials and get the project id. (I think you already done that).
2) Create a SignupUrl with signupUrls.create. (What you have done to get that JSON)
3) Keep the SignupUrl Name and redirect the user (or go) to the returned URL (inside the JSON posted).
3) Follow the procedure to create an enterprise.
This will start the creation of an enterprise to the signed Google Account.
4) At the end of the procedure you will be redirected to the callbackUrl specified inside signupUrls.create. Appended to the callbackUrl, as a GET query parameter, will be a token.
5) You must use the appended token to conclude the flow calling the API enterprises.create with these parameters:
The signup url name
The enterprise token returned as parameter
(optional) a request body with some enterprise parameters (logo, name, etc)
At the end of this coming and going between URLs and API calls, you will end with an Enterprise created on the Google Account and the enterprise ID in the form enterprise/<yourID> to interact with the API.
You can check all the Enterprise infos at the created Google Play for Work (or Managed Google Play) at http://play.google.com/work . Left menu "Administration Settings" at check your enterpriseId.
I have a Spreadsheet with some Apps Script functions bound to it.
I also have an Android client using Google Sheets API v4 to interact with that spreadsheet.
Is there a way for the Android client to call/run some function in the Apps Script code?
The reason I need to code to be run on the Apps Script side, and not simply on the Android client, is because I'm sending some email when something happens to the doc, and I would like the email to be sent from the owner account of the spreadsheet, and not from the Android user authenticated via the API.
I know I can trigger functions implicitly like by adding rows to a doc, but is there a way to directly run a specific function?
Yes. You can make GET and POST requests to Google apps-scripts. from anywhere that can make REST type calls including clients. If you need authentication there is also the apps-script client libraries. I wrote a short script for emailing from a request from one apps-script to another here. But, it would work if you called the emailing script from your client also.
Deploy your Google Apps Script as Web Apps > reference, by this way you can run function Get(e) or Post(e) and invoke other functions inside one of them with conditions....
You might have gotten the answer to your question. Just in case you have not, below are some points that may help with your development:
1) Create the server side script (i.e., Google Apps Script) function like usual:
function myFunction(inputVar) {
// do something
return returnVar;
}
2) Create a doGet(e) or doPost(e) function like below - can be in the same .gs file with the function in 1) :
function doGet(e) {
var returnVar = "";
if (e.parameter.par1 != null) {
var inputVar = e.parameter.par1;
returnVar = myFunction(inputVar);
}
return HtmlService.createHtmlOutput(returnVar);
}
3) Publish and deploy your project as webapp. Note the deployed URL.
4) From your Android client do HTTP call with the URL as: your_webapp_url?par1="input value"
I am looking for a strategy to have global objects that can be accessed across all users on all devices. My idea is to create an object or file and put it on Google Cloud Server, and using Datastore, Blobstore, or Cloud Storage (or maybe something else?), and have the object/file change as different users interact with it and alter variable values.
Now, how in the world can I do this - I am having a lot of trouble understanding the documentation that Google offers. Are there any convenient APIs for this? If so, how can these API's be accessed? Currently, I have followed the Android Studio "Hello Endpoints" setup, and I have a working backend module running on AppEngine.
So far I have learned how to create an API and API methods:
#Api(
name = "myApi",
version = "v1",
namespace = #ApiNamespace(
ownerDomain = "backend.myapplication.Mike.example.com",
ownerName = "backend.myapplication.Mike.example.com",
packagePath = ""
)
)
public class MyEndpoint {
/**
* A simple endpoint method that takes a name and says Hi back
*/
#ApiMethod(name = "sayHi")
public MyBean sayHi(#Named("name") String name) {
MyBean response = new MyBean();
response.setData("Hi, " + name);
return response;
}
}
So this shows I have successfully created a Cloud Endpoints / backend that goes with an App Engine project.
So, what I was hoping to do with this set up is to create an API method to save data to the cloud server, and then have other users on other devices to be able to retrieve that data.
If you're looking for something like "a big shared object" that lots of people can all change collaboratively, you might want to check out Firebase, which does this and keeps everyone in sync (and integrates nicely with Android and iOS).
What I'm trying to do is to authenticate my Android app to the Google Cloud Endpoint.
Basically the endpoints should only allow my Android app to access the methods and nothing else.
I have done these things -
Create a client id using my SHA1 value in Eclipse in the Google Cloud Console.
Create a web client id in the Google Cloud Console for my endpoint project.
Add both these client id's in the "#Api" mentioned on each endpoint.
Add an extra "user" parameter in the endpoint methods.
Regenerate and deploy the backend to the cloud.
But when I'm running this the "user" is always coming as "null". I'm at my wits end trying to find a proper working method for doing all this.
I've searched many forums but no proper answers anywhere.
Here's another similar post Restrict access to google cloud endpoints to Android app
This is the reference I'm using -
https://developers.google.com/appengine/docs/java/endpoints/auth
Has anyone here done this before? My main goal is to not allow unauthenticated apps and outside world to access the endpoints, for obvious security reasons. I don't want to use end-user based authentication since I want to keep my app very simple.
It sounds like it's working as intended. You control which client apps can call your endpoint methods via the client IDs as you have already done. The User parameter is coming in as null precisely because you aren't doing end-user authentication. The User parameter represents an actual real user (Google Account). So if you don't need end-user authenticated methods, you can just simply not define the User parameter, or else ignore the null value. You said your problem is that the User parameter is set null. What are you expecting it to be in this scenario?
You need to call authenticate on the client, then possibly the library you're using will 'inject' the user information.
Here's what worked for me :
Let's say you have the keys below :
static final String WEB_CLIENT_ID = "somekeyfor webclientid.apps.googleusercontent.com";
static final String ANDROID_CLIENT_ID = "somekeyfor androidclientid.apps.googleusercontent.com";
static final String ANDROID_AUDIENCE = WEB_CLIENT_ID;
Your Api anotation should look like this :
#Api(
name = "yourapiname",
clientIds = {CloudEndpoint.WEB_CLIENT_ID,CloudEndpoint.ANDROID_CLIENT_ID},
audiences = {CloudEndpoint.ANDROID_AUDIENCE},
version = "v1",
namespace = #ApiNamespace(
ownerDomain = "myapp.app.com",
ownerName = "myapp.app.com",
packagePath = ""
)
)
In the annotation below, notice how your audience is the variable --> ANDROID_AUDIENCE which is equal to WEB_CLIENT_ID.
Now in your app side, when you create the googleAccountCredential object, you should pass in the Web Client Id like this :
mAccountCredentials = GoogleAccountCredential.usingAudience(getApplicationContext(),"server:client_id:" + "yourwebclientID");
Note that even if this is properly done, your user object in the endpoint might still coming out as Null if the account name you pass in mAccountCredentials.setSelectedAccountName("accontname") does not exist in the device. Therefore make sure the account name you pass does exist in the Android device by going to --> (Settings/Accounts)
I want to create an Android client app for Google Documents List API, taking into account that it might be replaced by the Google Drive API in the near future. Therefore, I implemented authentication using google-api-java-client, which would presumably ease a transition to the new API if needed.
Now I'm trying to extend the DocsClient.java class, found in the shared-sample-docs project provided by Google, in order to be able to share documents with user contacts.
I found no better information on this matter than the following introduction written by #yanivinbar: http://javadoc.google-api-java-client.googlecode.com/hg/1.4.1-beta/com/google/api/client/googleapis/xml/atom/package-summary.html
From the Google Documents List API docs, I figured out ACL is used to give other users access to a specific document. However, it's not clear to me which methods I should implement to achive this or other common API related transactions.
You are right, you need to add ACL entry for your document entry. You can have method as below :
public void shareFile(DocumentListEntry documentListEntry,
AclScope.Type type, String value, String role)
throws MalformedURLException, IOException, ServiceException {
// Instantiate a AclEntry object to update sharing permissions.
AclEntry acl = new AclEntry();
// Set the ACL scope.
acl.setScope(new AclScope(type, value));
// Set the ACL role.
acl.setRole(new AclRole(role));
// Insert the new role into the ACL feed.
service.insert(new URL(documentListEntry.getAclFeedLink().getHref()), acl);
}
Here service is an object of com.google.gdata.client.docs.DocsService . Also you can specify different sharing types and roles on your documents.
Possible calls for above method can be
shareFile(entryObj,AclScope.Type.USER,"your email id",AclRole.OWNER);
shareFile(entryObj,AclScope.Type.DOMAIN,"domain name",AclRole.READER);