I have an Android app which writes/reads from an external SQL database through a PHP script. Both the database and the PHP script is hosted on Amazon Web Services (AWS). The app sends HTTP request to the PHP script, and the PHP script communicates with the database.
Are there easier ways to connect the app with the database? I feel like this method is kinda hacky. Or is this how it is done? Is it possible to avoid the PHP script entirely and just communicate with the database through Java in the app?
Below is the code for fetching everything in the database.
The php script:
$servername = "";
$username = "";
$password = "";
$conn = mysqli_connect($servername, $username, $password);
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "SELECT * FROM table";
$result = $conn->query($sql);
if($result->num_rows > 0){
while($row = $result->fetch_assoc()){
echo "rowname1: " . $row["rowname1"]. " rowname2: " . $row["rowname2"] . "\n";
}
} else {
echo "0 results";
}
$conn->close();
The Java code:
requestQueue = Volley.newRequestQueue(this);
String url = "";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
textDatabase.setText(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
textDatabase.setText(error.toString());
}
});
requestQueue.add(stringRequest);
This is the correct way to do that, via API.
Frontend Application (Android, iOS, browser) <-> API <-> Backend
You can connect direct to the database, but you should not. To be able to do that, you have to put user and password in your application. Doing this, how do you prevent users to connect on your database and changing all they want? There are many more points against this approach.
Look for REST APIs, or maybe GraphQL.
Related
I wrote android app to read json using volley.
If i use example URL from internet - i don't have problem, the data is read. But when i try to read data from local host, I am getting an error.
The same data i can see in web browser in my emulator.
my URL: "http://10.0.2.2/volley_sample/get_data.php"
my code:
private void sendGetRequest() {
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
String url = "http://10.0.2.2/volley_sample/get_data.php"; //it doesn't work
//String url ="https://reqres.in/api/users/2"; //it works
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 10 characters of the response string.
get_response_text.setText("Response is: " + response.substring(0, 10));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
get_response_text.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
adres "http://10.0.2.2/volley_sample/get_data.php" works in web browser in my emulator.
I tried also "http://192.168....", "127.0.0.1....", "localhost/volley_sample...." etc., and neither works.
adres "https://reqres.in/api/users/2" (example from internet) work without problem.
ofc. i added "<uses-permission android:name="android.permission.INTERNET"/>"
I have no idea what I am doing wrong :(
I'm very new to working with backend server stuff and nodejs. I'm trying to set up Stripe with my app and now trying to create a Connected account with stripe. Was following this https://stripe.com/docs/connect/collect-then-transfer-guide but I don't understand enough to make it work. How do I get information from the server or send it through to make the account.
this is what I got so far
binding.connectWithStripe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String redirect = "https://www.example.com/connect-onboard-redirect";
String url = "https://connect.stripe.com/express/oauth/authorize" +
"?client_id=" + "ca_Hdth53g5sheh4w4hwhw5h4weh5" +
"&state=" + 1234 +
"&redirect_uri=" + redirect;
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(view.getContext(), Uri.parse(url));
}
});
const express = require('express');
const app = express();
app.use(express.json());
const { resolve } = require("path");
const stripe = require('stripe')('sk_test_xxxx');
app.get("/", (req, res) => {
// Display landing page.
const path = resolve("./index.html");
res.sendFile(path);
});
app.get("/connect/oauth", async (req, res) => {
const { code, state } = req.query;
// Assert the state matches the state you provided in the OAuth link (optional).
if(!stateMatches(state)) {
return res.status(403).json({ error: 'Incorrect state parameter: ' + state });
}
// Send the authorization code to Stripe's API.
stripe.oauth.token({
grant_type: 'authorization_code',
code
}).then(
(response) => {
var connected_account_id = response.stripe_user_id;
saveAccountId(connected_account_id);
// Render some HTML or redirect to a different page.
return res.status(200).json({success: true});
},
(err) => {
if (err.type === 'StripeInvalidGrantError') {
return res.status(400).json({error: 'Invalid authorization code: ' + code});
} else {
return res.status(500).json({error: 'An unknown error occurred.'});
}
}
);
});
const stateMatches = (state_parameter) => {
// Load the same state value that you randomly generated for your OAuth link.
const saved_state = 'sv_53124';
return saved_state == state_parameter;
}
const saveAccountId = (id) => {
// Save the connected account ID from the response to your database.
console.log('Connected account ID: ' + id);
}
app.listen(4242, () => console.log(`Node server listening on port ${4242}!`));
The sign up page opens and can enter the test info but after submiting it's not actually creating the account in Stripe dashboard. Any help would be much appreciated
enter image description here
After you complete the Express account sign up, Stripe redirects your customer to the redirect URI you specified on your Connect OAuth url (looks like yours is https://www.example.com/connect-onboard-redirect).
You should redirect to a real page of yours here. The redirect URL will append query params containing the authorization code e.g. https://www.example.com/connect-onboard-redirect?code=ac_1234
where ac_1234 is the OAuth authorization code.
You need to parse out that authorization code and send it to your backend and complete the OAuth connection to actually connect that Express account to your Platform: https://stripe.com/docs/connect/oauth-express-accounts#token-request
Got the last piece of my puzzle. Didn't know how to communicate with nodejs and use the GET method. I used volley with this piece of code
RequestQueue queue = Volley.newRequestQueue(getContext());
StringRequest stringRequest = new StringRequest(Request.Method.GET, "http://10.0.2.2:4242" + "/connect/oauth",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(">>>>>>>>CONNECTED?", ">>>CONNECTED!!!<<<");
// enjoy your response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(">>>>>>>>>>ERRRRRRROR", error.toString());
// enjoy your error status
}
});
queue.add(stringRequest);
Hope that helps anyone else starting to learn nodejs :)
I am trying to create a simple registration page for my android app. I am passing parameters with URL String and Storing those parameters in Database. Whenever i try to use string directly in browser the data is added to database without any error. However, When i try to pass data from Android Volley i am getting HTTP Error 409.
I have checked everything and still confused why this error is appearing only when i try to run url string from android app.
URL String:-
http://myurl.com/api/register.php?name=ahmed&email=obaid.ahmed#gmail.com&password=12345&membertype=Artist&joindate=24-Feb-2019
Java Code:-
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, urlFinal, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// display response
Log.d("Response", response.toString());
uploadImageToServer();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
hideDialog();
}
}
);
First you need to understand about 409,
Explain here :- https://httpstatuses.com/409
And try to solve this on Server side where this Conflict issue occur.
And I recommend you to use URL Encoding before sending things in url,
Which is perform by :
Either by,
String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;
or By
String uri = Uri.parse("http://...")
.buildUpon()
.appendQueryParameter("key", "val")
.build().toString();
Which make your URL more compatible.
Or for More Better ways, There is an Library which i personally recommend to any android developer who love Light weight Volley for Api Integrations.
https://github.com/Lib-Jamun/Volley
dependencies {
compile 'tk.jamun:volley:0.0.4'
}
Cool Coding.
I am trying to convert a PHP-array into a Java ArrayList.
I have this PHP-Code which seems to have no syntax errors:
$password = "xxxx";
$host = "localhost";
$db_name = "xxxx";
$output = array();
$con = mysqli_connect("$host", "$user", "$password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
if (!mysqli_select_db($con, $db_name)) {
die('Could not select database: ');
}
$result = mysqli_query($con, "SELECT name FROM shopping_items"); //change to "name"
if (!$result) {
printf("Error: %s\n", mysqli_error($con));
exit();
}
while($row = mysqli_fetch_array($result, MYSQLI_BOTH))
{
$output[]=$row;
}
return $output;
mysqli_close($con);
?>
It takes one row from the table, so I should get back a PHP-array.
Now comes the hard part. In Java, I wrote the following code using the Volley library:
public void getShopping(String url) {
//init queue or get from somewhere
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest stringRequest;
stringRequest = new StringRequest(Request.Method.GET, url, //URL leads to PHP-File
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
shoppingItems.add(response); //shopping Items is an ArrayList
adapter.notifyDataSetChanged();
Toast.makeText(ShoppingListActivity.this, response, Toast.LENGTH_SHORT);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//got error
}
});
queue.add(stringRequest);
}
I want to have each item added to shoppingItems. But when printing the array out I get an empty string. I think that StringRequest is the wrong way to go but I don't know any other way. I read that using json_encode is possible but that seems unnecessarily complicated to me. Is there an easier way to do that?
I could not find an answer in previous SO questions. If at all possible, please provide help that involves Volley because it is pretty integrated in my code.
I am trying to connect my libGDX(java) android project with a mySQL database through a server side PHP scripting in order to implement a login process using POST method (this includes a username and password).
Therefore, i am facing unexpectable problems. For your info i am using XAMPP and APACHE web server locally.
What i am facing! Some times the PHP script sends back the following response string, as if not recognizing the POST parameters (despite the fact that POST message includes them and contain values (string)!!):
<b>Notice</b>: Undefined index: username in <b>C:\xampp\htdocs\login\login.php</b> on line <b>5</b><br />
<br />
<b>Notice</b>: Undefined index: password in <b>C:\xampp\htdocs\login\login.php</b> on line <b>6</b><br />
Some other, the debugger (on Android studio) which is enabled to show me the debugging logs, stops displaying any log after pressing 2-5 times the btnclickLogin() (is shown below), which implements the login activity.
This sounds to me that http connection hangs up and maybe the click button's listener does not respones any more!!!
The more strange one, is that SOMETIMES the same code, returns "success" and everything works fine.
The android code is the next
private void btnclickLogin() {
//Getting values from edit texts
Gdx.app.setLogLevel(Application.LOG_DEBUG);
final String username = usernamefld.getText().toString().trim();
final String password = passwordfld.getText().toString().trim();
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("username", username);
parameters.put("password", password);
Gdx.app.debug("Login process started.", "Username=/" + username + "/ Password=/" + password + "/");
HttpRequestBuilder requestBuilder = new HttpRequestBuilder();
HttpRequest httpRequest;
httpRequest = requestBuilder.newRequest().method(Net.HttpMethods.POST).url("http://192.168.1.2/login/login.php").content(HttpParametersUtils.convertHttpParameters(parameters)).build();
httpRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpRequest.setTimeOut(6000);
Gdx.net.sendHttpRequest(httpRequest, new HttpResponseListener() {
#Override
public void handleHttpResponse(Net.HttpResponse httpResponse) {
String status = httpResponse.getResultAsString().trim();
Gdx.app.debug("Return result by the server=", status);
if(status.contains("success"))
game.setScreen(new StartingScreen(game));
}
#Override
public void failed(Throwable t) {
String status = "failed";
Gdx.app.debug("Connection failed due to the next error:", t.getMessage());
}
#Override
public void cancelled() {
}
});
httpRequest.reset();
Gdx.app.debug("Exiting", "From login button function");
}
PHP scripts are
For login.php
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
//Getting values
session_start();
$username = $_POST['username'];
$password = $_POST['password'];
//Creating sql query
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
//importing dbConnect.php script
require_once('dbConnect.php');
//executing query
$result = mysqli_query($con,$sql);
//fetching result
$check = mysqli_fetch_array($result);
//if we got some result
if(isset($check)){
//displaying success
echo "success";
}else{
//displaying failure
echo "failure";
}
mysqli_close($con); }?>
For dbConnect.php
<?php
define('HOST',"localhost");
define('USER',"root");
define('PASS',"");
define('DB',"userlogging");
$con = mysqli_connect(HOST,USER,PASS,DB) or die('Connection failed: ' . $conn->connect_error);
$con->set_charset("utf8"); ?>
Please give a hand to overcome this problem and make the http connection "stable"!!
Thanks a lot.
Mishra sorry for the latest of my reply.
Yes, actually i have placed a print_r to see the values that come up to PHP script and found that both parameters were missing.
After so much searches on the internet and alternative solutions that found, i have not found out why does it happen. So, i replaced the HttpRequestBuilder.
Finally, in order to have a complete working code, i used the next and everything works fine now.
final String username = usernamefld.getText().toString().trim();
final String password = passwordfld.getText().toString().trim();
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("username", username);
parameters.put("password", password);
final HttpRequest httpRequest = new HttpRequest(Net.HttpMethods.POST);
httpRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpRequest.setHeader("Upgrade", "HTTP/1.1, HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11");
httpRequest.setUrl(LOGIN_URL);
httpRequest.setContent(HttpParametersUtils.convertHttpParameters(parameters));
httpRequest.setTimeOut(6000);
Thanks again for your help.