How to post the data in Node.js from android using retrofit - android

I am posting the data from Android to the Node.js. I am successfully able to call the Node.js post method and using restify able to get the Post data.
But when doing through express I am not able to get the post body in Node.js. I tried for many approaches from SO post but it seems none are working may be I am missing something.
The snippets are like:
Node.js
var express = require('express')
var request = require('request')
var http = require('http')
var bodyParser = require('body-parser')
var app = express();
app.set('port', (process.env.PORT || 5000))
app.use(express.static(__dirname + '/public'))
app.use(bodyParser.urlencoded())
app.use(bodyParser.json())
app.post('/search/addcomplaint',addComplaint)
function addComplaint(req,res,next){
console.log(req.body);
if (!req.body) return res.sendStatus(400)
res.send(201,user)
}
app.listen(app.get('port'), function() {
console.log("Node app is running at localhost:" + app.get('port'))
})
at Android Site I am making a retrofit call like this:
#Multipart
#POST("/search/addcomplaint")
public User search(#Part("complaint") String complaint);
when I used restify in Node.js I was able to get req.body but using express I am not getting the request body.

Related

Use http urls with Flutter http during development

I am developing a flutter app with backend running in localhost.
I am using http package for making http calls. I am creating the Uri like this:
Uri.https("localhost:8080", "api/v1/login");
but this Uri.https gives error, instead I need to use Uri.http.
The problem is when the app is ready for production I will have to manually edit code everywhere to use Uri.https instead of Uri.http.
Is there a better way to handle this?
You can simple use kReleaseMode to detect you are in release mode or not.
String baseUrl;
if (kReleaseMode) {
baseUrl = 'https://example.com';
} else {
baseUrl = 'http://localhost';
}
Uri uri = Uri.parse('$baseUrl/api/v1/login');
you can do it like this:
var baseUrl = 'http://localhost:8080/';
Future<void> _fetchData() async {
final response = await http.get(Uri.parse('$baseUrl/api/v1/login'));
print(response.body);
}

NodeJS HTTP POST receive an Image with Express

I am using Bluemix to develop a 'HTTP POST listener' with NodeJS. This server should be the link between an Android Application and a Watson Bluemix Service
This is my code
/*eslint-env node*/
// This application uses express as its web server
// for more info, see: http://expressjs.com
var express = require('express');
// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require('cfenv');
// create a new express server
var app = express();
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();
/* 'BODY PARSER - NOT WORKING' */
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); //Assuming JSON ENCODED INPUT
app.use(express.bodyParser({uploadDir:'/images'}));
// start server on the specified port and binding host
app.listen(appEnv.port, '0.0.0.0', function() {
// print a message when the server starts listening
console.log("server starting on " + appEnv.url);
app.post('/handle',function(request,response){
var image64=request.body.encoded_String;
var imageName=request.body.image_name;
/*OK LOG THIS (Encoded Base64 image)*/
console.log("IMG RECEIVED: " + imageName); //OK
console.log("ENCODED: " + image64); // = undefined (chunk problems?)
response.writeHead(200, { "Content-Type": "text/plain" });
response.write('Hello World - Example...\n');
response.end();
});
});
How can I receive a base64 encoded image and save it to a folder?
Thanks for you help!
String with image received in base64 has usually it's format written at the beginning which has to be removed (or at least I used to remove it).
var base64Data = str.replace(/^data:image\/png;base64,/, ""); // str - string with image
Then you have to save it with fs:
fs.writeFile("../dir/to/save/image.png", base64Data, 'base64', function(err) {});
And that's basically all.

How to make RESTAPI calls in android using node.js

I have created a RESTAPI in Node.js and trying it to invoke into my android application. But i am not able to make the request to the Node.js Rest API.
My code are as follows:
Node.js
var restify = require('restify');
var request = require('request');
var http = require('http');
var appContext = require('./config.js');
function labsAPI(jsonparseStr) {
return JSON.stringify(labsapi);
}
function searchbase(req, res, next){
var options = {
host: appContext.host,
path: appContext.path+req.params.name+appContext.queryString
};
cbCallback = function(response) {
var str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
jsonparseStr = JSON.parse(str);
json_res = labsAPI(jsonparseStr);
res.writeHead(200,{'Content-Type':'application/json'});
res.end(json_res);
});
}
http.request(options, cbCallback).end();
}
var server = restify.createServer({name:'crunchbase'});
server.get('/search/:name',searchbase);
server.listen(appContext.port, function() {
console.log('%s listening at %s', server.name, server.url);
});
After running my code like : localhost:8084/search/name
I am able to return the output to the browser a valid Json.
Now i want to consume this web service into my android application , I am not able to figure out how to do it.
I tried some of the example
http://hmkcode.com/android-parsing-json-data/
In the above blog in MainActivity.java i changed my url to
new HttpAsyncTask().execute("http://127.0.0.1:8084/search/name");
but it is displaying nothing
127.0.0.1 is the IP address for localhost. From your browser localhost resolves to your computer, from your Android device localhost resolves to your Android device, but your node application isn't running on it.
You need to figure out what's your computer's remote address. LAN or WLAN would be enough as long as your on the same network as your Android device.
Also make sure firewall settings allow access to your computer.

Android- Sharing local storage on multiple WebViews/Windows

I'm developping a mobile application, which should connect to a web server. The application is written with jQM and simply imported in an android web view. I tried to solve this problem using the jStorage plugin, but it seems that it's impossible to share the local storage between the different pages. So I tried to implement this, but it does not work and continues sending null.
Here are my code samples:
Javascript:
function getToken(authCode) {
var jsonUrl = mainUrl + "/auth/authorizeToken?grant_type=authorization_code&client_id=bc89fb879a64eb8e422b94d5c39&client_secret=b5c2974b78f7f3f7aee2bed182&redirect_uri=redirection&code="+authCode;
$.ajax({
url: jsonUrl,
type: "GET",
dataType: "jsonp",
success: function(data) {
localStorage.setItem( "access_token", data.access_token);
localStorage.setItem( "refresh_token", data.refresh_token);
localStorage.setItem( "logged", "true");
}
});
}
function valTokens() {
access_token = localStorage.getItem("access_token");
refresh_token = localStorage.getItem("refresh_token");
}
After that the values are set to null. The .java files are the same as in the sample from the link given.

C2DM with App Engine Python returns 401 error

I'm tyring to send a message to my mobile. Via browser I call the method that does this operation, I've logged the registrationId, authToken, etc.. and this is correct, because I tested in a local server and the message has been send to my phone using these keys.
However on App Engine, I have a 401 error on the result of the urlfetch.fetch for 'https://android.clients.google.com/c2dm/send'.
Or if this is a problem with authentication. I doubt it is the problem above, because the method is called, and the error happens right in the end of the method in my App Engine server.
Here is how I make the request to the C2DM servers:
params = {
'registration_id':registrationId,
'collapse_key':0,
'data.payload':encoded_msg
}
paramsByte = urllib.urlencode(params)
logging.info(registrationId)
url = 'https://android.clients.google.com/c2dm/send'
logging.info(token)
result = urlfetch.fetch(url=url,
payload=paramsByte,
method=urlfetch.POST,
headers={'Content-Type':'application/x-www-form-urlencoded',
'Authorization':'GoogleLogin auth='+token}
)
Any help would be appreciated. Thanks.
UPDATE
Now the client is running in a hosting server as suggested, and the
401 error happens when contacting
'https://android.clients.google.com/c2dm/send'.
However when using the following command on terminal with the same token and regId, it works.
curl --header "Authorization: GoogleLogin auth=your_authenticationid"
"https://android.apis.google.com/c2dm/send" -d
registration_id=your_registration -d "data.payload=payload" -d
collapse_key=0
Client code calling the method in server:
$.getJSON('http://myapp.appspot.com/method?userId='+userId+'&message='+theMessage+'&callback=?',
function(data)
{
console.log(data);
});
Full method code for server:
class PushHandler(webapp.RequestHandler):
'''This method sends the message to C2DM server to send the message to the phone'''
def get(self):
logging.info('aqui dentro')
userId = self.request.get('userId')
message = self.request.get('message')
callback = self.request.get('callback')
token = getToken(self) #this is a method I've implemented to get the token from C2DM servers by passing the SenderId and Password
registrationId = ''
contactNumber = ''
# Get the registrationId to send to the C2DM server to know which
# device it may send the message
regQuery = C2DMUser.all()
regQuery.filter('userId =', int(userId))
for k in regQuery:
registrationId = k.registrationId
# Builds the json to be sent to the phone
record_to_json = {
'userId':userId,
'message':message
}
data = []
data.append(record_to_json)
jsondata = simplejson.dumps(data) # Creates the json
# Encode the JSON String
u = unicode(jsondata, "utf-8")
encoded_msg = u.encode("utf-8")
params = {
'registration_id':registrationId,
'collapse_key':0,
'data.payload':encoded_msg
}
paramsByte = urllib.urlencode(params)
url = 'https://android.clients.google.com/c2dm/send'
logging.info(token)
result = urlfetch.fetch(url=url,
payload=paramsByte,
method=urlfetch.POST,
headers={'Content-Type':'application/x-www-form-urlencoded',
'Authorization':'GoogleLogin auth='+token}
)
data = []
params_key = { 'status_code':result.status_code }
data.append(params_key)
self.response.headers['Content-Type'] = 'application/json'
jsondata = simplejson.dumps(data)
if result.status_code == 200:
logging.info(result.status_code)
self.response.out.write('' + callback + '(' + jsondata + ')') # handle the JSONP
else:
logging.info(result.status_code)
self.response.out.write(result.status_code)
The package name of your code must match the one you gave when you signed up for the c2dm account. For Java, if you gave com.myapp when you signed up, your c2dm calls must occur within that package. Not sure how this translates to Python, though.
As far as the C2DM part is concerned, everything seems okay. If you are saying that with the same credentials it works with your local server, I am guessing that it should work on App Engine.
As far as the XMLHttpRequest error is concerned, you can't issue requests through the XMLHttpRequest to other domains or sub-domains. So, you cannot issue your request from localhost to yourSite. A solution would be using JSONP.

Categories

Resources