No response to UnityWebRequest on build to http server - android

I've got an Android app I'm building with Unity that logs info on a simple python http server (hosted on a Digital Ocean Droplet). Here's my coroutine for poking the server:
IEnumerator pokeServer()
{
Debug.Log( "Establishing Server Connectivity..." );
using( var www = UnityWebRequest.Get( ServerURL ) )
{
Debug.Log( "Send Web Request" );
ServerStatus = ConnectionStatuses.AttemptingToConnect;
yield return www.SendWebRequest();
if( www.isNetworkError || www.isHttpError )
{
if( www.isNetworkError )
{
Debug.Log( "NETWORK ERROR: " + www );
}
else
{
Debug.Log( "HTTP ERROR: " + www );
}
ServerStatus = ConnectionStatuses.Unavailable;
}
else
{
Debug.Log( "Success! Server available!" );
ServerStatus = ConnectionStatuses.Connected;
}
}
}
If I run this on the Unity Editor, everything works fine. I can get a response from my server without issue. If I build and run this on an Android, the request is not sent to my server and I get no error message. The last line in the above code that's run is "yield return www.SendWebRequest();"
I've looked at the logcat, and there's no error. My server never gets any requests. However, if I poke "https://www.google.com," I do indeed get a response. This leads me to believe that this is some sort of http vs https issue, but I have no idea where to start. This code has been working for me for a very long time. Any advice would be very welcome!

I'd been using this phone from University of Pennsylvania's wireless network. It turns out that I can make an http request from a desktop but I can't do it from a phone. I took one of the devices home and tried it from my personal wifi and it all worked fine.

Related

xamarin android : httpclient PostAsync

we have an app under xamarin android build with visual studio 2017.
this app works since three years without any problems.
since two weeks and I don't know why actually some device can't sync with our back end.
It's really strange because nothing has change in this part .
this error does not appear on all devices but on one or two from time to time
we use the dll httpClient for to sync the datas with our backend.
If i put a break point inside the postAsync I have an exception with this -> Cannot access a disposed object. Object name: 'System.Net.Sockets.NetworkStream
Any one has an idea about how to solve this ? also what does it meam ?
Here is it the code of the postAsync method :
thanks for our time and comment guys
public override HttpResult ExecutePost(Uri target, string body)
{
var client = new HttpClient();
client.MaxResponseContentBufferSize = MaxHttpResponseBufferSize;
try
{
var requestContent = new StringContent(body, RequestContentEncoding, RequestContentType);
var response = client.PostAsync(target, requestContent).Result;
if (response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsStringAsync().Result;
return new HttpResult(content, null, null);
}
return new HttpResult(null, "Response is empty", response.StatusCode.ToString());
}
catch (Exception e)
{
return new HttpResult(null, "Problem with the HttpPost", e.Message);
}
}
I experienced the same issue. Have been battling for 6 hours on this issue.
If you read the error, I was getting (Failed to connect to localhost/127.0.0.1:7113). If you put localhost in your browser or swagger tool it will work but if you put https://127.0.0.1:7113/api/weatherforecast in your browser it will not work. It will give you a certificate problem.
So I think you have to resolve 127.0.0.1 to localhost with https certificate on your local dev machine.
I'm building a MAUI app with Visual Studio 2022 Preview.
So I solved this issue by deploying my API to AZURE.
Then update to the azure url for example:
string apiUrl = "https://weatherforecast.azurewebsites.net/api/weatherforecast";
and then it worked brilliantly. Like super brilliantly.
Here is my code:
public void LoginAsync()
{
HttpClient client = new HttpClient();
string apiUrl = "https://weatherforecast.azurewebsites.net/api/weatherforecast";
UserCredentials.EmailAddress = LoginUIEntity.EmailAddress;
UserCredentials.Password = LoginUIEntity.Password;
string serialized = JsonConvert.SerializeObject(UserCredentials);
var inputMessage = new HttpRequestMessage
{
Content = new StringContent(serialized, Encoding.UTF8, "application/json")
};
inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
var message = client.PostAsync(apiUrl, inputMessage.Content).Result;
if (message.IsSuccessStatusCode)
{
var apiResponse = message.Content.ReadAsStringAsync();
UserCredentials = JsonConvert.DeserializeObject<UserCredentials>(apiResponse.Result);
if (UserCredentials.IsValid)
{
UserCredentials.IsLoggedIn = true;
}
else
{
ErrorMessage = "Invalid credentials supplied.";
}
}
}
catch (Exception ex)
{
ErrorMessage = "An error has occurred. Please contact support if the error persists.";
}
}
}
thanks for the link your provide.
I've try up the buffer on the postasync / try to sync in wifi OR 3G / delete special character in json / ...
but nothing work
we have move the prod database to the test and try to sync the data to the test database with postman. with postman the result was ENTITY TOO LARGE !
Json is size > 1.2 mega and the default value inside IIS is set to 1 mega
Here is it the problem ...
thanks problem solve

HTTP POST request from app works on iPhone but not on Android phone

In my ionic app I have a POST request to do login. This works fine on an iPhone but when I test the app on an Android phone the server returns a 404 Not Found error.
My code for making the HTTP request looks like this:
loginUser: function(email,password) {
var em = email.replace(/\s/g,'');
var pw = password.replace(/\s/g,'');
var url = apiDomain + '/api/v1/user/login/';
if (em && pw) {
return $http.post(url, {
auth: {
email: em,
password: pw
}
}).then(function successCallback(response) {
alert('login success. response = '+JSON.stringify(response));
return response;
}, function errorCallback(response) {
alert('login fail. response = '+JSON.stringify(response));
return -1;
});
}
},
Can anyone think of a reason why this would work on an iPhone but not on an Android phone?
The text shown by the alert() in the errorCallback is:
login fail. response = {
"data":"",
"status":404,
"config":{
"method":"POST",
"transformRequest":[null],
"url":"http://cues-server-dev.elasticbeanstalk.com/api/v1/user/login/",
"data":{
"auth":"{
"email":"aa#aa.aa",
"password":"alcohol"}},
"headers":{
"Accept":"application/json,text,plain,*/*",
"Content-Type":"application/json;charset=utf-8"}},
"statusText":"Not Found"}
I am at a loss to understand why this works on an iPhone but not an Android phone.
It may be to do with the URL prefix. Have you tried using:
apiDomain = #"https://cues-server-dev.elasticbeanstalk.com"
or
apiDomain = #"http://www.cues-server-dev.elasticbeanstalk.com"
or some other variant.

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.

How do I enable Third-Party Cookies under Phonegap and Android 3.2?

I am using $getJSON to hit a node.js endpoint under Phonegap and Android. The code looks like this
$.getJSON(
serverURL + "/login?callback=?",
"playerId=" + playerId + "&pwd=" + pwd,
function(data){
theCallbackFunction.call(null, JSON.parse(data));
},
function(jqXHR, textStatus, errorThrown) {
alert('error ' + textStatus + " " + errorThrown);
}
);
In response to the login request, my server sends back a session cookie. This cookie is only accepted and returned in subsequent AJAX requests if 'Third-Party Cookies' are enabled in the browser. I have found that older Android devices (e.g. 2.2) allow this by default but new ones (3.2) do not.
Is it possible to force Phonegap to enable Third-Party Cookies for my Android application?
I had a similar problem when trying to authenticate with my server. I instead resorted to the use of localStorage. See the code below or here.
var store = window.localStorage,
request = {
url: {SERVER_URL},
headers : {
Cookie: store.getItem('session')
},
complete: function (jqXHR, status){
if (status != 'success') {
console.log('ajax status: failure');
} else if (store.getItem('session') != null) {
console.log('ajax status: session exists');
} else {
console.log('ajax status: saving cookie');
var header = jqXHR.getAllResponseHeaders();
var match = header.match(/(Set-Cookie|set-cookie): (.+?);/);
if (match) {
session = match[2];
store.setItem("session", session);
}
}
}
}
$.ajax(request);
In the above, I'm checking for the localStorage variable 'session' and if it exists, it will send the stored cookie. If it doesn't exist, it will take the 'set-cookie' paramater sent in the headers by the server, match the pertinent part and store it in the 'session' variable of localStorage.
Phonegap does not support cookie abstraction. Never really needed to as there are already apps/plug-ins that do. Plus it is intended to wrap up the functionality of the phone/device, not the browser. You CAN however do this with a jQuery plug-in.
https://github.com/carhartl/jquery-cookie

unable to connect to JSON service in android application of Titanium studio

i am trying to do login application which takes id and password..when i click on logi button then it will connect to our local server by JSON..with the specified URL..the code is..
var loginReq = Titanium.Network.createHTTPClient();
loginReq.onload = function()
{
var json = this.responseText; alert(json);
var response = JSON.parse(json);
if (response.data.status == "success")
{ alert("Welcome ");
}
else
{ alert(response.data.status);
}
};
loginReq.onerror = function(event)
{
alert(event.toSource());
//alert("Network error");
};
loginBtn.addEventListener('click',function(e)
{ if (username.value != '' && password.value != '')
{
var url = 'our local url action=login&id='+username.value+'&pwd='+password.value;
loginReq.open("POST",url);
loginReq.send();
}
else
{
alert("Username/Password are required");
}
});
Here it is not connecting our URl..so it is entering into loginReq.onerror function...instead of loginReq.onload function..why it is throwing run time error.. The same code working fine with Iphone..
The Run Time Error is..
TypeError:Cannot call property toSource in object{'source':[Ti.Network.HttpClient],specified url} is not a function,it is a object.
This is wat the error..please let me Know...
Apparently the toSource() function does not exist in android, as it is an object. Try debugging and see what the object event contains.
You could do that by adding a line above the alert line, and adding a debug line to it.
Look in debug mode and see all variables
"toSource()" is not a documented function for either platform, and I also do not see it in the source for Titanium Mobile. If you aren't getting the error on iOS, I'm guessing it is because the error handler isn't getting called. Perhaps your emulator or device does not have internet access, whereas your iOS simulator or device does?
Regardless, error handling in the HTTPClient normally looks something like this:
loginReq.onerror = function(e)
{
Ti.API.info("ERROR " + e.error);
alert(e.error);
};

Categories

Resources