While trying to fetch contacts using google account of user , I am facing some issues after using people API.It only returns few email addresses out of all listed ones.Access token and all scopes have been set correctly.
Code for following :
People peopleService = new People.Builder(httpTransport, jsonFactory, credential)
.build();
ListConnectionsResponse response = peopleService.people().connections().list("people/me")
.setPageSize(500).setSortOrder("FIRST_NAME_ASCENDING")
.setAccessToken(tokenResponse.getAccessToken())
.setAlt("json")
.setRequestMaskIncludeField("person.names,person.emailAddresses,person.phoneNumbers")
. execute();
connections = response.getConnections();
Instead of this if I use contact API of google then I am getting more no of email addresses than people.Code for contact API :
URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
ContactFeed resultFeed = myService.getFeed(feedUrl, ContactFeed.class);
// Print the results
System.out.println(resultFeed.getTitle().getPlainText());
for (ContactEntry entry : resultFeed.getEntries()) {
....
.....
.......
}
I want to know if there is any difference between both of them and which one i have to use for better results or am I missing something. please suggest. Thanks..!!
People API is more up-to-date. Reading through Google's blog announcement, People API simplifies what needed to be separate calls to Google+ API and Contacts API. Now you only need to use one.
"The new People API uses the newest protocols and technologies and
will eventually replace the Contacts API which uses the GData
protocol"
When getting the user's list of connections, be sure to specify the correct scopes when using it.
https://www.googleapis.com/auth/contacts - Requests that your app be given read and write access to the contacts in the authenticated user’s Google Contacts.
https://www.googleapis.com/auth/contacts.readonly - Requests that your app be given read access to the contacts in the authenticated user’s Google Contacts.
Check this link for similarities and differences between People API and Contacts API.
I'm not sure if there is any issues with the java code, but if you look at the request that is sent out it should be like this:
URL:https://content-people.googleapis.com/v1/people/me/connections?pageSize=300&requestMask.includeField=person.names%2Cperson.email_addresses&sortOrder=FIRST_NAME_ASCENDING&key=
I was able to get all the contacts with the correct email and name. If you google "manage google contacts" you will see a list of contacts. From there take that number, and just print out the connection count which should match. You just need to make sure the pageSize is big enough or you have to handle paging to get all the contacts.
Also i realized that the requestMask.includeField is really sensitive to what parameters and spaces you put. "person.name,person.email_addresses" worked and "person.name, person.email_addresses" did not.
With the older contact api, you can query the q parameter which I don't think the people api provides this ability. I think the ability to filter your search by key words is important to reduce the request size.
Related
I want to integrate National Identification Authority (NIDA) API for Tanzania in my Android application. In my application, user will enter their NIDA number and i want to retrieve user information according to NIDA number.
I have just one PDF file to guide me, it says that i need to have 3 to 4 certificates ie. Serve CA Certificate n etc. And after that 4 to 5 encryptions are needed to implement to request NIDA API. And no other information are given like what is the end point for the request?
As i couldn't find anything else on the internet related to NIDA API call, i couldn't even start the programming! So i have not done any coding yet, so not sharing any codes.
If anyone knows anything about the NIDA API call, please let me know.
NIDA does not have a developer portal or documentation online one has to contact them and ask for access. However I heard once in the news that "NIDA will start charging entities who are using its Data - Ref
https://www.thecitizen.co.tz/tanzania/news/nida-to-start-charging-entities-using-its-data-2712730"
But there is no official portal for accessing their API. The legal way to obtain access to their API is to visit their office for Technical Support.
That being said, a simple quick hack solution will be to use existing private sector that uses NIDA API to your advantage since it's REST Full API without verification token or access token
Here is an example :
Where NIN = National Id Number. Eg: 19760517372270000217
`curl -XPOST -H 'Content-Length: 0' -H "Content-type: application/json" 'https://ors.brela.go.tz/um/load/load_nida/{NIN}`
You should expect a json data object in return if the ID is valid or exist
Using the Mobile Backend Starter (MBS) Android classes (those distributed as a sample project when creating a new project in Google Dev Console and demoed at Google I/O 2013) I'm able to insert new entities to the cloud datastore via calls to CloudBackendMessaging.insertAll or .updateAll. The latter will create entities if none exist so seems functionally identical to insert for new records.
The insertion/creation works fine. However when I attempt to update existing entries in the datastore, I received permissions errors e.g. (from the backend log)
Method: mobilebackend.endpointV1.updateAll
Error Code: 401
Reason: required
Message: Insuffient permission for updating a CloudEntity: XXXXXX by: USER: YYYYYYY
which results in a matching access error in the logcat client side.
In all cases I am using Secured access authenticating with a valid Google account (my own).
The entities being inserted are thus showing as "owned" by my user ID with "updated by" and "created by" showing my Google account's email address.
However when the update of the existing record is made, using exactly the same CloudBackendMessenger object and thus same credentials etc. the backend is telling me I can't update due to permissions issues. But surely if I just made the entity with the same credentials this can't be correct? Looking at the documentation it appears that I should be able to edit entities owned by the same user ID in all cases (regardless of the KindName and whether it is prepended [public], [private] or nothing).
Can anyone who has received permissions errors on UPDATES via Mobile Backend Starter for Datascore please shed any light? I have been banging my head over this for most of today.
I've faced the similar error "Insuffient permission for updating a CloudEntity" when using cloudBackendAsync.update(cloudEntity). I resolved it by making sure the cloudEntity has it's createdAt field set. createdAt is autogenerated and I think I am not supposed to touch it. But it worked for me. In my case I am first obtaining list of cloud entities. This is when I get createdAt field of cloud entities. Then when I am updating I setting the createdAt field from previously obtained entities.
Edit: Had to do similar thing for owner field also.
Similar to one of the comments above, I successfully got around this by getting the original CloudEntity before doing the insert/update/delete function.
CloudQuery cq = new CloudQuery("datastoretype");
cq.setLimit(1);
cq.setFilter(Filter.eq("_id",id));
cloudEntity.setId(id);
mProcessingFragment.getCloudBackend().get(cloudEntity, handler);
Thereafter it was trivial to do the following:
mProcessingFragment.getCloudBackend().update(cloudEntity, handler);
The docs definitely ought to be more clear on this, whether it is a strict requirement or bug.
The answers posted so far work around the problem if you don't mind all users being able to access the entity you are trying to update. However, a better solution that retains the access permissions is detailed by google here - https://cloud.google.com/cloud/samples/mbs/authentication
If you want to pass the user’s Google Account info to the backend on
each call, use the CloudBackend#setCredential() method (also available
on the subclasses, CloudBackendAsync and CloudBackendMessaging) to set
a GoogleAccountCredential object before calling any Mobile Backend
methods.
GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(this, "<Web Client ID>");
credential.setSelectedAccountName("<Google Account Name>");
cloudBackend.setCredential(credential);
Setting credientials enables the client to operate when the backend is
in “Secured by Client ID” mode and also sets createdBy/updatedBy/owner
properties of CloudEntity automatically.
I have been doing a lot of research recently on securing my app engine. Currently, I've been reading through the question below and the links in that question:
How do I restrict Google App Engine Endpoints API access to only my Android applications?
However, it doesn't answer my problem. My question is similar to the question above, restricting access to my endpoint API to only my app. The guy seemed to have got it working when he inputs a correct email into the credentials.
My question is if I can achieve the same results without having to input any credentials. I want it so that only my app can use my endpoint API so to prevent other apps from abusing it and using up my quota. I already got a client id for my android application, and have placed it within my #API annotation. To test if it worked, I made a random value for the client id in the #API notation of another api class. However, my app was still able to use methods from both class. Any help?
-Edit-
From reading from the docs and researching further, the endpoint way of authorizing apps is by authenticating the user and for my API to check if user is null. My question is that in the process of authenticating the user, is Google somehow able to read my app's SHA1 fingerprint and authorize it to its list of client ids? If so, how can I replicate this process in my endpoint so that I check the SHA1 fingerprint of the app making the request and compare it to a set value? I don't understand the mechanics behind the endpoints very well, so correct me if I am understanding this wrong.
If the android app has access, then the user has access. A motivated party has many options for inspecting your protocol, including putting the device behind transparent proxy or simply running the app through a debugger. I do suggest running your app through ProGuard before publishing, as this will make the process [a bit] more difficult.
Ultimately, you'll need to make your appengine API robust against untrusted parties. This is simply the state of the web.
How you can protect your endpoint API is described here: http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html
The secret is that you request a token from Google Play using the following scope: audience:server:client_id:9414861317621.apps.googleusercontent.com where 9414861317621.apps.googleusercontent.com is your ClientId.
Google Play will look up the id at your endpoints app and return a Google-signed JSON Web Token if it finds the id. Then you pass that id in with your request. Above article says you should pass it in with the body. I would possibly rather add another parameter for that because otherwise you can't pass your own entities anymore. Anyway, your server backend receives the token, and you ask Google as described if it is authentic, before you process the API request.
If you pass in the token using an extra parameter, you can catch it on the server side by adding HttpServletRequest to your endpoint signature and then using request.getHeader("Yourname") to read it out. Make sure you never add the parameter as a URL parameter as it may be logged somewhere.
public void endpointmethod(
// ... your own parameters here
final HttpServletRequest request
) throws ServiceException, OAuthRequestException {
request.getHeader("YourHeaderName") // read your header here, authenticate it with Google and raise OAuthRequestException if it can't be validated
On the Android side you can pass in your token when you build the endpoint api, like this, so you don't have to do it with each and every request:
Yourapiname.Builder builder = new Yourapiname.Builder(AndroidHttp.newCompatibleTransport(), getJsonFactory(), new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
httpRequest.setHeader(...);
}})
Hope this helps you make your endpoints API secure. It should.
I am a little confused by these APIs. I am trying to integrate Google+ with my Android app and I am struggling a little. I have been successful at logging in a user using OAuth2, created a Verifier, obtained an accessToken and made a request to Google+ API.
Here is my line of code requesting to see the user information:
OAuthRequest request = new OAuthRequest(Verb.GET, "https://www.googleapis.com/plus/v1/people/me");
This successfully returns a jSON object containing my information/public.
Whenever I change the endpoint to this:
"https://www.googleapis.com/plusDomains/v1/circles/p4643b3a289c42c44"
attempting to use the PlusDomains, I get a forbidden message.
What I really want to do is manage circles for a user (simply add a page to their "Following" circle. That is all I need.
What am I doing wrong? Am I trying to use the wrong endpoint? Does Google+ API allow me to do POST requests?
Every piece of information is helpful.
Thanks in advance!
Google+API and Google+Domains API are different APIs (activating/allowing one does not activate/allow the other).
The Domains API can be considered as a more powerfull (more functionnalities) than Google+API.
See comparison of the two API here on the official doc.
Link here
In my android application, I would like to retrieve the birthday field from google.com/contacts, as this field isn't synchronised in the android contacts application.
How can I have a read access to google contacts ?
I saw the Google contacts APIs, did I have to use it ? which one ? the Portable version ?
Or is there a simple way to read these contacts, as Android does when there is a synchronisation ?
Thanks in advance
There used to be a hack before the AccountManager was reased, I started a thread about a year ago on the android developer group, but it has been removed. There was an undocumented method that you had to access through reflection. I can't seem to find it anywhere now, like google has deleted the thread or something. I found something similar below, but it's not the one I had working.
http://donpark.org/blog/2009/01/24/android-client-side-oauth
At worst case, most devices that are out now, should eventual get 2.1. So you could just make them login then validate and get the auth key from google, and if they are on 2.1 use the AccountManager and don't bother them with the credentials. something like below
WebRequest req = HttpWebRequest.Create(
#"https://www.google.com/accounts/ClientLogin? accountType=GOOGLE&Email=them#gmail.com&Passwd=pass&service=gbase&source=sadboy");
WebResponse resp = req.GetResponse();
string all;
using (StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()))
all = sr.ReadToEnd().Trim();
int auth = all.IndexOf("auth=");
string auth = all.Substring(auth, all.Length - auth);
https://developer.android.com/about/dashboards/index.html
It should be possible since android 2.0 using AccountManager.
There are no tutorials nor samples, I don't have access to any >=2.0 device to try it out.
See http://code.google.com/p/android/issues/detail?id=1073#c28
As I understand you should be able to getAuthToken fo Google account and pass it in Authorization header as here Authorization: GoogleLogin auth=yourAuthToken