I'm trying to test out an updated appengine version without ruining my live version. The current code is:
themeendpoint.Builder endpointBuilder = new themeendpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(),
new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest httpRequest) throws IOException {
}
}
);
themeendpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
Which works fine for the default version. I'm trying to access the "dev" version that I uploaded. I understand that normally you are supposed to add the version at the beginning like "dev.project.appspot" but I'm struggling to get this into the Android App. I tried adding the following:
endpointBuilder.setRootUrl("https://dev.project.appspot.com/_ah/api/");
Just before creating the endpoint. When running the app I get the following error:
java.io.IOException: Hostname 'dev.project.appspot.com' was not verified
I'm at a loss as to how to access my non-default version.
Turns out I almost had it right. Per this link I need to use "-dot-" notation for HTTPS. Plus, I was missing a small piece of the URL. Full line of code is:
endpointBuilder.setRootUrl("https://dev-dot-project.appspot.com/_ah/api/");
Related
I want to build an android client that can interact with the WooCommerce based site using the Rest Api provided by WooCommerce
This is my android code. I am using OkHttp library for networking.
public class MainActivity extends AppCompatActivity {
OkHttpClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String cred = Credentials.basic("ck_...","cs_...");
OkHttpClient client = new OkHttpClient
.Builder()
.build();
Request req = new Request
.Builder()
.addHeader("Authorization",cred)
.url("http://10.0.2.2:8080/woocom/wp-json/wc/v2/products")
.build();
client.newCall(req).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d("api resp", "onFailure: ");
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("Api resp", "onResponse: "+response.body().string());
}
});
}
}
This is the error log after running the app
com.example.android.woocommerceapiintegration D/Api resp: onResponse: {"code":"woocommerce_rest_cannot_view","message":"Sorry, you cannot list resources.","data":{"status":401}}
What am I doing wrong here. I tried out the NodeJS client provided by WooCommerce which works fine.
Also I cannot access the rest api via curl according to the command given in the docs
Can someone tell me what I am doing wrong ?
Update: The selected answer is what needs to be done in production environments, and is the technically right thing to do. If you want to avoid the hassle of OAuth while on a development server, I have answered it seperately.
The 401 code indicates an authorization issue with your connection. Specifically your issue is caused by your usage of BasicAuth with an HTTP connection.
The WooCommerce REST API Documentation indicates that BasicAuth is only supported for HTTPS connections, and HTTP connections must use OAuth 1.0a "one-Legged" authentication to "ensure" your credentials aren't intercepted by an attacker.
It's important to note that even with OAuth 1.0a, an HTTP connection will never be truly secure and it's highly recommended to switch your app over to a secure HTTPS connection.
Meanwhile, in order to get your code working, you'll have to implement the OAuth 1.0a authentication method for your Android app.
You can find a complete set of instructions and a complete project example of OAuth 1.0a implementation for Android here. The GitHub Page has an excellent guide with step-by-step instructions on using the library linked above. Just make sure that when using the code provided you make sure to account for the fact that you're using OKHttp. Luckily, the author has commented the code in the instructions very well and makes a note of changes to make when using something like OkHttp.
You could use Retrofit and simply write an Interceptor which takes care of the 'nitty-gritty' part as detailed in the documentation here.
You could also follow the step by step guide detailed in the WooCommerce Documentation here to generate your OAuth signature and finally encodedUrl and then pass it to your http client. This processs involves: (see the Documentation for detailed specs for each section)
Collecting the request method and URL
Collecting all oauth_* parameters and encoding them into a single string using percent encoding and correct ordering. For Example (taken from WooCommerce Docs):
oauth_consumer_key=abc123&oauth_signature_method=HMAC-SHA1
Create the base string for the signature by joining the values from 1 and 2. For example: (once again from Docs):
GET&http%3A%2F%2Fwww.example.com%2Fwp-json%2Fwc%2Fv2%2Forders&oauth_consumer_key%3Dabc123%26oauth_signature_method%3DHMAC-SHA1
Finally generate the signature using HMAC-SHA1 (HMAC-SHA256 is also supported).
Personally I would recommend either the first or second approach. "No need to reinvent the wheel".
EDIT:
You can look at this question which discusses how you can use self-signed certificates in a local dev environment with OkHttp.
Thanks akseli for answering my question.I've also awarded you the bounty and thanks for adding to my knowledge. Despite everything, I've found a simple solution to this problem.
My concern was that while development, We generally don't have an https based server and hence have to go through that tedious OAuth based process which won't be used is production anyway as the server we will probably use will be https enabled.
So, to use basic authentication while on an http dev server, you need to go to [your wordpress directory]/wp-content/woocommerce/includes/api. Find out class-wc-rest-authentication.php. This class handles the api authentication. Find the authenticate function which looks like this
public function authenticate( $user_id ) {
// Do not authenticate twice and check if is a request to our endpoint in the WP REST API.
if ( ! empty( $user_id ) || ! $this->is_request_to_rest_api() ) {
return $user_id;
}
if ( is_ssl() ) {
return $this->perform_basic_authentication();
}
return $this->perform_oauth_authentication();
}
comment out the condition is_ssl and simply return $this->perform_basic_authentication(), so that in any case, basic authentication is performed.
Note:This is a hack just to avoid the hassle of OAuth authentication while in dev environment and is not at all recomended in production.
I am working on building an Android app which uses the Watson Conversation API. I am following the tutorials mentioned here and here.
However, it seems that quite a few of the Api's functions are deprecated. For example, the ConversationService is now Conversation.
Similarly, I am having an issue running this piece of code:
MessageRequest request = new MessageRequest.Builder()
.inputText(userStatement)
.build();
It says Cannot resolve symbol Builder. Since the MessageRequest Class no longer has the builder(I guess). Any way around this situation?
Try it..
MessageOptions newMessage = new MessageOptions.Builder().workspaceId("")
.input(new InputData.Builder(userStatement).build()).context(context).build();
MessageResponse response = service.message(newMessage).execute();
I think you are using older version of sdk.
Update it https://github.com/watson-developer-cloud/java-sdk/releases
Message request is no longer available. Use MessageOptions.
I'm trying to use non default App Engine app version in Android app. The default App Engine app version is 1 and I've uploaded a new version 2 and want to test it using Android app.
The default root path to the app instance is as follows:
xxx.appspot.com
Both instances are accessible (or should be) using:
https://1.xxx.appspot.com // version 1
https://2.xxx.appspot.com // version 2
The first problem is testing it through browser. In Chrome you can't test it, because of error message Your connection is not private. Looks like certificate issue for *.appspot.com:
NET::ERR_CERT_COMMON_NAME_INVALID
You can workaround this using Firefox and add given site as trusted one. So assume the second version is tested through the browser, time to test it using Android app.
I changed the endpoint root URL passing the new URL to the builder:
builder.setRootUrl(https://2.xxx.appspot.com);
That fails with:
java.io.IOException: Hostname '2.xxx.appspot.com' was not verified
at com.android.okhttp.Connection.upgradeToTls(Connection.java:1026)
at com.android.okhttp.Connection.connect(Connection.java:963)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:405)
A quick search on SO and there's a quick and dirty solution (I'd not use this in production, even not to test the app. Of course host name checking should be performed e.g. using default verifier then if the default returned false using my fallback verifier):
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
And the final result:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(ProGuard:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.set(ProGuard:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(ProGuard:312)
No matter which version I use, it ends up with 404. The only valid URL is https://xxx.appspot.com I'm sure the method I'm trying to call exists on the endpoint because I can call it using Firefox.
Any suggestions how to test the new App Engine app version with Android app? Is the certificate validation failure a bug, or is this the correct behavior that *.appspot.com matches only xxx.appspot.com but doesn't match x.xxx.appspot.com?
Obviously the solution was in the documentation:
Please note that in April of 2013, Google stopped issuing SSL
certificates for double-wildcard domains hosted at appspot.com (i.e.
..appspot.com). If you rely on such URLs for HTTPS access to your application, please change any application logic to use "-dot-"
instead of ".". For example, to access version "1" of application
"myapp" use "https://1-dot-myapp.appspot.com" instead of
"https://1.myapp.appspot.com." If you continue to use
"https://1.myapp.appspot.com" the certificate will not match, which
will result in an error for any User-Agent that expects the URL and
certificate to match exactly.
In short I had to replace 2. with 2-dot-
Problem with the new App engine connected android application projects for the google eclipse plugin? This is the "Big Daddy" sample shown at goolge i/o 2011. My sample project compiles and the android app appears to work fine and registers with the server. However when I send a message from the server I get the following: Having issue with sample project. Android appears to work fine and registers with the server and the c2dm server, however I cannot send a message.
Also of note on the server is a c2dmconfig datastore object. It has fields for authToken and c2dmUrl. The authToken has a token, however the c2dmUrl is NULL. I suspect this is where my problem lies, but not sure how to fix it.
Thanks Patrick
I found this question by wondering the same thing, if the c2dmUrl being null is a problem. It would seem that this is not an issue though. If you look at the C2DMConfig (the entity that you are referencing), there is a function called "getC2DMUrl". Here it is:
public String getC2DMUrl() {
if (c2dmUrl == null) {
return DATAMESSAGING_SEND_ENDPOINT;
} else {
return c2dmUrl;
}
So null is a supported value for this. If a specific URL isn't specified, it simply returns it to the default.
I'm creating an Android app and trying to use Google Places API through Google APIs Client. I've been following this example:
http://ddewaele.blogspot.com/2011/05/introducing-google-places-api.html
I'm having problems creating a HTTP Transport Object to use in creating the HTTP Request Factory. Everything compiles fine in eclipse, but when I debug while running on my phone, I get a classnotfound on the first line here:
HttpTransport transport = new ApacheHttpTransport();
HttpRequestFactory httpRequestFactory = createRequestFactory(transport);
public static HttpRequestFactory createRequestFactory(HttpTransport transport) {
return transport.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest request) throws IOException {
request.headers.authorization = "...";
}
});
}
According to the JavaDoc for the HTTP Transport Class:
Android:
Starting with SDK 2.3, strongly recommended to use
com.google.api.client.javanet.NetHttpTransport. Their Apache HTTP Client
implementation is not as well maintained.
For SDK 2.2 and earlier, use com.google.api.client.apache.ApacheHttpTransport.
com.google.api.client.javanet.NetHttpTransport
is not recommended due to some bugs in
the Android SDK implementation of
HttpURLConnection.
I'm running on 2.2, so I tried using the ApacheHTTPTransport. I've also tried the NetHTTPTransport, but I get the same thing (classnotfound).
Any ideas/examples?
Thanks!
In order to run the Places API in an Android environment using the Google APIs Client, you'll need to have the following dependencies in your Android project :
M2_REPO/commons-codec/commons-codec/1.3/commons-codec-1.3.jar
M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
M2_REPO/com/google/api/client/google-api-client/1.4.1-beta/google-api-client-1.4.1-beta.jar
M2_REPO/com/google/api/client/google-api-client-googleapis/1.4.1-beta/google-api-client-googleapis-1.4.1-beta.jar
M2_REPO/com/google/code/gson/gson/1.6/gson-1.6.jar
M2_REPO/com/google/guava/guava/r08/guava-r08.jar
M2_REPO/org/apache/httpcomponents/httpclient/4.0.3/httpclient-4.0.3.jar
M2_REPO/org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar
M2_REPO/org/codehaus/jackson/jackson-core-asl/1.6.5/jackson-core-asl-1.6.5.jar
M2_REPO/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar