Get data from PHP and MySQL in Android Java

In this tutorial, we will teach you how you can get data from database using PHP and MySQL in Android Java. We will be using Volley for sending HTTP request.

Following will be the structure of users table from where we will fetch data. You can add more fields as per your need. Important thing here is auto-increment primary key ID:

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

We will be sending an HTTP request to a PHP server, here it is it’s code:

get-data.php

<?php

    $userId = $_POST["userId"];
    $conn = mysqli_connect("localhost", "root", "root", "tutorials");

    $sql = "SELECT * FROM `users` WHERE `id` = '" . $userId . "'";
    $result = mysqli_query($conn, $sql);

    if (mysqli_num_rows($result) > 0)
    {
        $row = mysqli_fetch_object($result);

        echo json_encode(array(
            "status" => "success",
            "message" => "Successfully logged in",
            "user" => $row
        ));
    }
    else
    {
        echo json_encode(array(
            "status" => "error",
            "message" => "User not found"
        ));
    }
    exit();

?>
  1. First we are getting userId which will be sent by android app using POST method.
  2. Then we are connecting with MySQL database using host, username, password and database name respectively.
  3. Then we are fetching data from users table using his ID.
  4. Check if record does not exists, then simply send an error message as response. All responses must be in JSON string.
  5. If exists, then simply fetch that row, and send in response. That will be received by android.

Now include Volley in your android project’s app/build.gradle:

dependencies {
    ...

    // To convert JSON string into Java class object
    implementation 'com.google.code.gson:gson:2.8.5'

    // To send an HTTP request to PHP server
    implementation 'com.android.volley:volley:1.1.1'
}

First, we need to define the structure of data received from server. Create a class in your android project’s java package named UserModel.java, you can add more fields as per need:

public class UserModel {

    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Now simply send an HTTP request using Volley and convert the response into this UserModel class:

String url = "http://localhost/tutorials/get-data.php";
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                try {
                    JSONObject responseJson = new JSONObject(response);
                    String status = responseJson.getString("status");
                    String message = responseJson.getString("message");

                    if (status.contains("error")) {
                        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
                    } else {
                        UserModel userModel = new Gson().fromJson(responseJson.getString("user"), UserModel.class);

                        // do whatever you want with userModel
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        error.printStackTrace();
        Toast.makeText(getApplicationContext(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
    }
}) {
    @Override
    protected Map<String, String> getParams() {
        Map<String, String> params = new HashMap<>();
        params.put("userId", "1");

        return params;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> params = new HashMap<>();
        params.put("Content-Type", "application/x-www-form-urlencoded");
        return params;
    }
};

// To prevent timeout error
stringRequest.setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

// Add the request to the RequestQueue.
stringRequest.setShouldCache(false);
queue.add(stringRequest);
  1. We are sending request to get-data.php file.
  2. The method should be POST. We are sending userId parameter and sending the value in it. You might be storing this ID in shared preference. Learn how to save values in Shared Preference from here.
  3. When the response is received, we are simply converting that into JSON. Getting status and message strings.
  4. If the status is “error”, then simply display a message in Toast.
  5. Then convert the “user” key into UserModel class object and save it in object named userModel.
  6. Now you can use that object however you want.

Now that you have learned to fetch data from database using PHP and MySQL and convert that into Android Java class object, learn how to save the data from android to PHP and MySQL.

Upload android gallery image to PHP, MySQL – Java

In this article, we will show you how you can upload image from your android gallery to PHP server.

Introduction

We will create a profile page in an android application where we wil display the user profile picture, name and a submit button. You can also display other fields as per your project. And when the form is submitted, we will send an HTTP request from android to PHP server that will save the user’s selected picture in PHP server and save its path in MySQL database along with its ID.

We will also discuss how you can display an image from a live server in an android application. We will be displaying the user profile image in circular form as in the screenshot.

In your app/build.gradle, make sure to add Volley, Glide and CircleImageView dependency:

implementation 'com.android.volley:volley:1.1.1'

// Used to display image from live HTTP server in imageview
implementation 'com.github.bumptech.glide:glide:3.7.0'

// To display image in circular form
implementation 'de.hdodenhof:circleimageview:2.2.0'

MySQL table structure

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` text NOT NULL,
  `picture` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

We will have a “picture” name column in your user’s table. ID will be the primary unique key used to identify the user.

Now come to the android part. First, we will be creating a layout for the profile page. To keep the things simple, we are using name, and picture in the profile page:

layout/activity_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_login">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="10dp" />

    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/image"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:text="Username"
        android:textColor="#ffffff"
        android:textSize="22sp"
        android:textStyle="bold" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/username"
        android:orientation="vertical"
        android:padding="36dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Full Name"
            android:textColor="#ffffff" />

        <EditText
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:backgroundTint="#ffffff"
            android:inputType="text|textCapWords"
            android:maxLines="1"
            android:textColor="#ffffff"
            android:textColorHint="#ffffff" />

        <Button
            android:id="@+id/btn_update"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:text="Update"
            android:textSize="12sp" />
    </LinearLayout>
</RelativeLayout>

In android, dp – Density-independent Pixels – is an abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion.

  1. We have a circular image view where user’s profile picture will be displayed. User can click on picture to edit.
  2. Then name of user below profile picture.
  3. A <LinearLayout> to display input fields and button vertically aligned.
  4. <EditText> to change name. You can add more fields, that depends on your project.
  5. And a <Button> which when clicked will submit the form and send an HTTP request to the PHP server to save the picture in folder and its path and in MySQL database. Also to store the name in MySQL.

Now in your profile activity’s onCreate method paste the following code. We will explain that line-by-line:

ProfileActivity.java

private final int PICK_IMAGE_REQUEST = 71;

private EditText name;
private ImageView image;
private Button btnUpdate;

private String selectedPicture = "";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_profile);

    name = findViewById(R.id.name);

    image = findViewById(R.id.image);
    image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
        }
    });
}

When image is clicked we will send an intent telling the android to open the gallery for images along with request ID in a variable PICK_IMAGE_REQUEST.

On image selected from gallery – Android

You will be asked to select an image from gallery. When the image is selected and the app is opened again, an event will be received in onActivityResult() function, so we will override it. It will contain the image data:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
            && data != null && data.getData() != null) {
        Uri filePath = data.getData();
        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
            
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            byte[] imageBytes = baos.toByteArray();
            selectedPicture = Base64.encodeToString(imageBytes, Base64.DEFAULT);

            byte[] bytesImage = Base64.decode(selectedPicture, Base64.DEFAULT);
            Glide.with(getApplicationContext())
                    .load(bytesImage)
                    .asBitmap()
                    .into(image);
        } catch (IOException e) {
            Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }
}

We are converting user selected image into Bitmap and converting that into base64 since we can only upload the android gallery image on server via base64. Saving the base64 string in variable named selectedPicture. And then displaying that in image view using Glide.

You can compress the image if you want. And you can decide to set the format to PNG or JPEG.

Upload image to PHP server

Now when update button is clicked, we will send an HTTP request containing base64 string of picture, along with name, and ID of user. You might be getting the user ID from shared preference. Learn how to save value in shared preference from here. Paste the following code in your activity’s onCreate() method.

btnUpdate = findViewById(R.id.btn_update);
btnUpdate.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String url = "http://localhost/tutorials/Http.php";
        // Instantiate the RequestQueue.
        RequestQueue queue = Volley.newRequestQueue(getApplicationContext());

        // Request a string response from the provided URL.
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Toast.makeText(getApplicationContext(), "Profile has been updated", Toast.LENGTH_LONG).show();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("id", "9");
                params.put("name", name.getText().toString());
                params.put("picture", selectedPicture);
                params.put("update_profile", "1");

                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };

        // To prevent timeout error
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        // Add the request to the RequestQueue.
        stringRequest.setShouldCache(false);
        queue.add(stringRequest);
    }
});
  1. We are sending a request using Volley to Http.php, this will be the file which will save the image file and save its path in MySQL database.
  2. Request will be POST and it must have parameters of username, picture base64 picture and user ID. You can get user ID from shared preference. Learn how to save value in shared preference from here.
  3. When the response is received from server, then we are simply displaying a success message in Toast.
  4. We are setting retry policy to 50 seconds, which means that the request will wait for 50 seconds till the response is received from server.
  5. And we have disable the cache so it will always return fresh response from server.

Now we will move to the server side. In your Http.php file, paste the following code and we will explain that line-by-line:

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$conn = mysqli_connect("localhost", "root", "root", "tutorials");

if (isset($_POST["update_profile"]))
{
    $id = $_POST["id"];
    $name = $_POST["name"];
    $picture = $_POST["picture"];

    $file_path = "profile/" . $id . ".jpg";

    file_put_contents($file_path, base64_decode($picture));

    $sql = "UPDATE `users` SET `name`='" . $name . "',`picture`='" . $file_path . "' WHERE id='" . $id . "'";
    mysqli_query($conn, $sql);

    echo "Profile has been updated";
    exit();
}

?>
  1. First we are enabling all error reporting for PHP.
  2. Then we are connecting with database.
  3. Then check if the request is for update profile. We are sending this value from Volley from android.
  4. Then get the name and base64 string of picture.
  5. Create a folder named “profile” in your project’s root directory.
  6. Then decode the base64 string and file_put_contents will save the file in “profile” folder.
  7. Finally update the MySQL database and send the response back to android app.

Display image from live server

Now that you have successfully uploaded an image from your android app to PHP server and saved its path in MySQL database. Now is the time to display that when user open the profile activity. Paste the following code in the onCreate() method when you successfully get the user records from database:

Glide.with(this)
    .load("http://localhost/tutorials/profile/9.jpg")
    .asBitmap()
    .diskCacheStrategy(DiskCacheStrategy.NONE)
    .skipMemoryCache(true)
    .into(image);

Where in load() function you will place the user actual image file store in your PHP server.

By default, Glide using caching to load images faster which are already loaded. But during development, we always want to fetch fresh data. So you can disable caching by setting DiskCacheStrategy to none.

So, now you can successfully upload image from your android gallery and save it in PHP server.

If you want to know how to fetch data from PHP and MySQL in your android app, you can follow this.

User registration in Android, Java, PHP, and MySQL

User registration is used in almost every android app today.

We will create a registration form in an android application using Java. And when the form is submitted, we will send an HTTP request from android to the PHP server that will save the user’s data in the MySQL database.

MySQL table structure

Following will be the table structure for users table:

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` text NOT NULL,
  `username` text NOT NULL,
  `password` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

Users table will have a unique ID that will be used to uniquely identify the user in the whole users table. We are adding a “primary key” index to the ID field. And also an “AUTO_INCREMENT” that will automatically generate the next ID number. For example, if there are 4 users already registered and a new user tries to register, then the MySQL database will automatically assign his ID to 5.

User registration in android – Layout

Now come to the android part. First, we will be creating a layout for the registration form. To keep the things simple, we are using name, username, and password in the registration form:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_login"
    android:paddingLeft="36dp"
    android:paddingTop="15dp"
    android:paddingRight="36dp">

    <ImageView
        android:id="@+id/logo"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/logo" />

    <TextView
        android:id="@+id/tv_Signup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/logo"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:text="Create an account"
        android:textColor="#ffffff"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_Signup"
        android:backgroundTint="@android:color/white"
        android:hint="Full Name"
        android:inputType="text|textCapWords"
        android:maxLines="1"
        android:textColor="#ffffff"
        android:textColorHint="#ffffff" />

    <EditText
        android:id="@+id/username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/name"
        android:backgroundTint="@android:color/white"
        android:digits="qwertyuiopasdfghjklzxcvbnm1234567890"
        android:hint="Username"
        android:inputType="text"
        android:maxLines="1"
        android:textColor="#ffffff"
        android:textColorHint="#ffffff" />

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/username"
        android:backgroundTint="@android:color/white"
        android:drawablePadding="5dp"
        android:hint="Password"
        android:inputType="textPassword"
        android:maxLines="1"
        android:textColor="#ffffff"
        android:textColorHint="#ffffff"
        android:textCursorDrawable="@null" />

    <Button
        android:id="@+id/btn_register"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_below="@+id/password"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="Register" />

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_login"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />
</RelativeLayout>

In android, dp – Density-independent Pixels – is an abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion.

  1. <RelativeLayout> it will have full width and height to the screen, has an image as background (as in the screenshot). Will have padding from left (36dp), right (36dp), and top (15dp).
  2. <ImageView> to display the logo of the app or company. It has 100dp widths and 100dp height
  3. <TextView> to display the heading of the page.
  4. <EditText> is the input field for name. It will be below the heading. Its text will be in white color. Each word will be capitalized.
  5. Second <EditText> is for username. It will be below the name field. You can only write a-z and 0-9 digits, no special characters will be allowed.
  6. <android.support.v7.widget.AppCompatEditText> this field is for password. User cannot see the text entered in this field.
  7. <Button> which when clicked will submit the form and send an HTTP request to PHP server to store that data in MySQL database.
  8. Finally a <ProgressBar> to display a loading circle when the request is sent to the server. And will be hidden when the response is received from the server.

Call HTTP request – Volley

In your app/build.gradle, make sure to add Volley dependency:

dependencies {
    ....

    implementation 'com.android.volley:volley:1.1.1'
}

Now in your register activity’s onCreate method paste the following code. We will explain that line-by-line:

ProgressBar progressBar = findViewById(R.id.progressBar);
progressBar.setVisibility(View.GONE);

EditText username = findViewById(R.id.username);
EditText password = findViewById(R.id.password);
EditText name = findViewById(R.id.name);

Button btn_register = findViewById(R.id.btn_register);
btn_register.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        String usernameText = username.getText().toString().trim();
        String passwordText = password.getText().toString().trim();
        String nameText = name.getText().toString().trim();

        if (!usernameText.isEmpty() && !passwordText.isEmpty() && !nameText.isEmpty()) {

            progressBar.setVisibility(View.VISIBLE);
            btn_register.setEnabled(false);

            String url = "http://localhost/tutorials/Http.php";
            // Instantiate the RequestQueue.
            RequestQueue queue = Volley.newRequestQueue(this);

            // Request a string response from the provided URL.
            StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            try {
                                JSONObject responseJson = new JSONObject(response);
                                String status = responseJson.getString("status");
                                String message = responseJson.getString("message");

                                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();

                                progressBar.setVisibility(View.GONE);
                                btn_register.setEnabled(true);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                    Toast.makeText(getApplicationContext(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                }
            }) {
                @Override
                protected Map<String, String> getParams() {
                    Map<String, String> params = new HashMap<>();
                    params.put("name", name.getText().toString().trim());
                    params.put("username", username.getText().toString().trim());
                    params.put("password", password.getText().toString().trim());
                    params.put("registration", "1");

                    return params;
                }

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> params = new HashMap<>();
                    params.put("Content-Type", "application/x-www-form-urlencoded");
                    return params;
                }
            };

            // To prevent timeout error
            stringRequest.setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

            // Add the request to the RequestQueue.
            stringRequest.setShouldCache(false);
            queue.add(stringRequest);

        } else {
            Toast.makeText(getApplicationContext(), "Please fill all details", Toast.LENGTH_LONG).show();
        }
    }
});
  1. First, we are creating an instance of ProgressBar and hiding it by default. We will only display when the request is sent.
  2. Then we are getting the name, username, and password input fields objects.
  3. After that, we are checking if any of the fields are empty, then display an error in Toast.
  4. Now, we are displaying the progress bar and disabling register button, so the user cannot click multiple times.
  5. Then we are sending a request using Volley. The request method should be POST.
  6. getParams() will have all our parameters. We are sending a name, username, and password along with an additional value “registration” that will be used to tell the server to handle the request for registration.
  7. Response received from the server will be a JSON string, so we are converting that into JSONObject, and displaying server response message in a Toast.
  8. And finally, we are hiding the progress bar and enable the register button again. So if there is any error, then the user can click on the register button again.

Save user data in MySQL using PHP

Now come to the server-side. As you see we are sending the request to Http.php so we must have that file in our server. This file should have the following content, we will explain that line-by-line:

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$conn = mysqli_connect("localhost", "root", "root", "tutorials");

if (isset($_POST["registration"]))
{
    $username = $_POST["username"];
    $name = $_POST["name"];

    $sql = "SELECT * FROM `users` WHERE `username` = '" . $username . "'";
    $result = mysqli_query($conn, $sql);

    if (mysqli_num_rows($result) > 0)
    {
        echo json_encode(array(
            "status" => "error",
            "message" => "Username already exists"
        ));
        exit();
    }

    $password = password_hash($_POST["password"], PASSWORD_DEFAULT);

    $sql = "INSERT INTO `users`(`name`, `username`, `password`) VALUES ('" . $name . "', '" . $username . "', '" . $password . "')";
    mysqli_query($conn, $sql);

    echo json_encode(array(
        "status" => "success",
        "message" => "Account has been created",
        "user_id" => mysqli_insert_id($conn) . ""
    ));
    exit();
}
  1. First, we are enabling all PHP errors. So if there is any error it will be received in error response in the android app.
  2. Then we are connecting with the database using host: port, username, password, and database name respectively.
  3. After that, we are checking if the request received is for registration, then get the name, username, and password fields from a POST request.
  4. Now, check from the database if the user with the same username already exists in the user’s table, if yes, then send an error response and stop the script using exit() function.
  5. Then convert the plain text password into an encrypted hash, so even if your database got hacked, no one will know the actual password of your users.
  6. And finally, run an INSERT query to save the database in MySQL database and send the success response back to the android app.
  7. We are also sending the inserted ID in response. So if you want to use the newly inserted ID in the MySQL table, you can get it from mysqli_insert_id function and passing the connection as a parameter.

User registration has been done in your android project. You can also learn how to authenticate the user for login and save his data in android Shared Preferences.

UIDatePicker timezone fix – Swift iOS

UiDatePicker in Swift has some timezone issues, so we will teach you how you can fix it.

Convert time to different timezones

If you are working on UIDatePicker in your Swift project, you might come across a problem that when fetching the value from UIDatePicker it usually returns the value by mapping with your timezone. But we want to have the actual value from the date picker as it is (without having timezone mapping).

UIDatePicker timezone fix

You can use the following function to get the actual value selected from date picker:

datepicker.date.description(with: .current)

Assuming datepicker is your outlet for type UIDatePicker. You can also prevent the user from selecting previous dates by writing the following line at the end of your viewDidLoad() function:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    
    datepicker.minimumDate = Date()
}

Video tutorial:

Easy way to save the class object in user defaults – Swift iOS

When it comes to saving the class object in user defaults, there is a hard way to do using NSKeyedArchiver class. But there is an easy to do using JSONEncoder and JSONDecoder classes. In this tutorial, we will teach you how you can:

  1. Save the class object in defaults using Swift by encoding in JSON.
  2. Get a class object from defaults by decoding from JSON.
  3. Remove the class object from defaults.

First, create a model class in Swift which will be the class that needs to be stored in user defaults.

User.swift

import Foundation

class User: Codable {
    public var id: Int = 0
    public var name: String = ""
}

Make sure it is a type of Codable protocol, this will help to convert the class into JSON. Set the default values to all data members, integers to 0, and strings to empty string. Then we will create a file which will have all the functions to save, retrieve, and remove the class object value from user defaults, we name that class LocalStorageManager.

LocalStorageManager.swift

import Foundation

class LocalStorageManager {
    
    public func saveUser(user: User) {
        do {
            
            let jsonEncoder = JSONEncoder()
            let jsonData = try jsonEncoder.encode(user)
            let json = String(data: jsonData, encoding: .utf8) ?? "{}"
            
            let defaults: UserDefaults = UserDefaults.standard
            defaults.set(json, forKey: "user")
            defaults.synchronize()
            
        } catch {
            print(error.localizedDescription)
        }
    }
    
    public func getUser() -> User {
        do {
            if (UserDefaults.standard.object(forKey: "user") == nil) {
                return User()
            } else {
                let json = UserDefaults.standard.string(forKey: "user") ?? "{}"
                
                let jsonDecoder = JSONDecoder()
                guard let jsonData = json.data(using: .utf8) else {
                    return User()
                }
                
                let user: User = try jsonDecoder.decode(User.self, from: jsonData)
                return user
            }
        } catch {
            print(error.localizedDescription)
        }
        return User()
    }
    
    public func removeUser() {
        let defaults: UserDefaults = UserDefaults.standard
        defaults.removeObject(forKey: "user")
        defaults.synchronize()
    }
}
  1. Create a global data member that will be the key used to identify the object in user defaults.
  2. saveUser function will receive the User class instance as a parameter, convert that as JSON string and save in defaults.
  3. getUser function will return the user class instance by decoding from the JSON string. Here, we will handle all the validations that might be useful for decoding the JSON data.
  4. removeUser function is used to delete the user class instance from defaults.

To use this, we are going to simply call these functions from our main view controller file.

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let user: User = User()
        user.id = 565
        user.name = "Adnan"
        
        LocalStorageManager().saveUser(user: user)
        
        let cacheUser: User = LocalStorageManager().getUser() 
        print(cacheUser)
        
        LocalStorageManager().removeUser()
        
        let cacheUserAgain: User = LocalStorageManager().getUser() 
        print(cacheUserAgain)
    }
}
  1. First, we are creating an instance of user class and set the values.
  2. Then we are saving in defaults.
  3. After that, we are retrieving the saved user class object and printing it out for debugging.
  4. Finally, we are removing it from defaults and printing it out.

Learn how to do a CRUD operation using local storage in Swift UI

Local storage Swift UI – CRUD

How to export and download CSV in Node JS

Learn how to export and download CSV file in Node JS.

Video tutorial:

First, we create a folder and open the command prompt or terminal in it using the following command:

cd "path of folder"

Then you can initialize the NPM by running the following command:

npm init

Then you can install the required modules:

npm install express http fs fast-csv

We will be using express as the main module for all types of requests and responses. HTTP for starting the server, fs stands for File System, and fast-csv to create CSV files. We have created a file named “server.js”. So you can start the server by running the following command in your terminal:

nodemon server.js
# or node server.js

Create a folder named “public” in root of your Node JS folder, here we will save the CSV file. Now your “server.js” file will have the following content:

var express = require("express");
var app = express();
var http = require("http").createServer(app);
var fileSystem = require("fs");
var fastcsv = require("fast-csv");

app.use("/public", express.static(__dirname + "/public"));

http.listen(3000, function () {
    console.log("Connected");

    app.get("/exportData", function (request, result) {

        var data = [{
            "id": 1,
            "name": "Adnan",
            "age": 29
        }, {
            "id": 2,
            "name": "Ali",
            "age": 31
        }, {
            "id": 3,
            "name": "Ahmad",
            "age": 33
        }];

        var ws = fileSystem.createWriteStream("public/data.csv");
        fastcsv
            .write(data, { headers: true })
            .on("finish", function() {

                result.send("<a href='/public/data.csv' download='data.csv' id='download-link'></a><script>document.getElementById('download-link').click();</script>");
            })
            .pipe(ws);
    });
});
  1. We are first creating instances of all modules.
  2. Then we are telling the server that we will be saving files in the “public” folder.
  3. After that, we are starting the server at port 3000.
  4. Then we are creating a GET route which when accessed will create a CSV file and download it in the user’s browser.
  5. Now, we are creating an array which will be the data of CSV file. You can replace that with your own array.
  6. Then we are creating a write stream, and in that, we are sending the path of CSV file. In our case, it is in the “public” folder and named “data.csv”.
  7. Write the data array using a fast-csv module. When the writing finished, simply create an anchor tag and add an attribute “download“. Set the href to the path of file. And fire a click event using Javascript.
  8. We are using pipe() function that will add the write stream in fast-csv queue.

Explore our more tutorials and projects developed in Node JS.

[wpdm_package id=’556′]

Social Networking Site in Node JS and Mongo DB

The social networking site is a project developed in Node JS, and Mongo DB. It has all the functionality that you need to build a social network for your local community.

A social networking service is an online platform that people use to build social networks or social relationships with other people who share similar personal or career interests, activities, backgrounds, or real-life connections. Social networking services vary in format and the number of features.

wikipedia

Features list:

  1. Login and registration
  2. Update Profile
  3. Posts
  4. Like, comment, and reply
  5. Share posts in timelines, pages, and groups
  6. Notifications
  7. Search
  8. Email confirmation
  9. Reset password
  10. Create friends
  11. Create pages
  12. Create groups
  13. Realtime chat
  14. See people who viewed your profile
  15. Edit and delete the post
  16. Load more button
  17. Send images and videos in the chat
  18. See people who liked and shared your post
  19. Encryption on chat messages
  20. Ban & delete user
  21. Filter bad/abusive words
  22. Adult image validation
  23. Ban post
  24. Create events
  25. Embed YouTube videos in the post
  26. Customer support
  27. Advertisement (boost post)
  28. Emoji comments
  29. Like, dislike, comment on stories
  30. People nearby
  31. Group chat

Demo

Requirements:

Introduction

The social networking site is a project developed in Node JS and Mongo DB. It has all the functionality that you need to build a social network for your local community. Node JS is becoming a rising programming language for backend servers, it is fast and easy to learn. If you know Javascript, you already know Node JS.

On the other hand, Mongo DB is quickly becoming a standard for creating schema-less applications where the structure of your database is not important. It is widely being used in large systems to scale easily.

This project has a basic version that allows you to download the code for free and set it up in your local system. In the source files, a file named “How to install.txt” will guide you on how you can set up the project in your system. But if you are still facing a problem, you can always contact me.

Login and registration

In the basic version, you will avail of the authentication functionality that includes login and registration of the user. Passwords are encrypted before being stored in Mongo DB. The project uses JSON Web Token (JWT) for storing logged-in user’s information. JWT is used to transmit information securely between client and server. After logging in, the user will be able to update his profile picture and cover photo. Uploaded files are stored in the Node JS server using the “fs” module which stands for File System and the path of the uploaded file is stored in Mongo DB.

Post with caption, image, and video

Now come to the most important part of any social networking site, POSTS. What makes a social network great is the number of posts, so you should allow users to create posts, update their status, what they are doing, etc. The basic version can create posts using text, images, or video. Posts created by the user will only be viewed by his friends. When the post is created, the user will like the post, comment on a post, and reply to any comment. Posts can also be shared on your timeline, so you can pick any post you like and hit the “share” button, and will be displayed on your timeline as well.

When someone likes your post, comments on your post, or replies to your comment, a notification will be received on the left side of your home page. You can view a list of all notifications received and notification will be marked as read once opened.

Search

You can search people by their name, username, or email address. You can also search groups and pages as well by their name. This will create 3 tabs on the search page, first for users, second for pages, and third for groups.

Email verification

In terms of authentication, you will be able to verify the user by his email address during registration. When someone registers, an email will be sent to him with an instruction to verify their email address. Users who have not verified their emails will not be able to log in. This will help you know that the users you have on your site are actual users, not robots.

Reset password

This project also comes with the functionality to reset the password. This gives users the ability to reset their passwords if they have forgotten. When someone types his email to reset the password, the system will check if the email exists then it will send an email with a link to reset the password. When that link is opened it will confirm that it is the valid link and show the field to enter a new password.

Create friends

You can create friends by searching for people by their name, and then send them a friend request. The other person will be able to respond to that request, he can either decline or accept the request. Once accepted, you both will be able to view each other’s posts in your timeline.

Create pages

You can create pages by entering the page name, cover photo, and a short description of the page. Then you will be able to add posts to that page as well. When someone searches for that page, he will be able to view all the posts on that page. Users will be able to like the page, and once liked they will be able to view the page’s posts in their timeline as well.

Create groups

This pro version also allows you to create groups by entering the group’s name, cover photo, and a short description of the group. Once the group is created, people will be able to see it in their search results, they will send a request to join the group. Only you (admin) will be able to decline or accept the group request. Once accepted, the user will become a member of that group. Members are allowed to add posts in that group and all the other members will be able to view it in their timeline.

Realtime chat

One of the most demanding functions of a social network is chat. You make friends chat with them, in this version you will be able to have a real-time secure chat between 2 friends. We have used Sockets for real-time communication, all the messages are also being stored in Mongo DB.

People who viewed your profile

It also has a functionality where you can see a list of all people you have viewed your profile. When someone visits someone’s profile, we are storing his record in Mongo DB along with the current date and time. Then the other person will see a list of people who viewed his profile along with the time that person visited your profile recently.

Since you are creating posts, you must be able to edit and delete posts. You can edit your own created posts and you can also delete your created posts as well. Once the post is updated, it will be updated on all social networks. Although it is Mongo DB (non-relational) still manages to update the post’s document in all places. The same goes for delete, once the post is deleted, it will be deleted all over the social network.

It also has a functionality that we call “load more”. It allows you to load more posts without having to reload the page. When the social network is opened, the first 30 posts will be fetched and displayed in the browser. When the user scrolls to the bottom, a button is displayed at the bottom of the page which when clicked will fetch the next 30 posts. You can change the number of posts as you wish.

You can send images and videos in a chat with your friends. All attachments sent are being stored in the Node JS file system. You can also preview the files before sending them. Images and videos are not being compressed, so you can send high-quality images without having to worry that the system will reduce the quality of images, it will not reduce the quality of images or videos.

Share posts

You will be able to share posts in your timeline, pages you have created, and the groups you have joined.

You will be able to view a list of all people you have liked and shared your post. This is helpful for a social network where you want to know who has liked and shared your post.

This project has 15 major features that are essential for this social network:

  1. Message encryption.
  2. Customer support.
  3. Ban & delete the user.
  4. Filter bad or abusive words.
  5. Adult image validation.
  6. Ban the post.
  7. 24-hour stories
  8. Audio files
  9. Events
  10. YouTube links
  11. Advertisement (boost post)
  12. Emoji comments
  13. Like, dislike, and comments on stories
  14. People nearby
  15. Group chat

Let’s view each in detail.

1) Message encryption on chat

First, is the encryption for chat messages. When you are having a chat with your friend, instead of saving the messages in plain text, we have added the functionality to encode the message during sending and decoding the message during receiving. Thus, making the chat encrypted. The below screenshot shows how messages will be stored in the database. So only the receiver can see the message correctly.

You can check our tutorial on encryption and decryption from here.

2) Customer support

The second is customer support. If users are having a problem with any function or want to ask something, they can contact your social network’s customer support. It can be accessed from the left sidebar. Users can create a new ticket, a ticket is a problem that the user is facing. They can enter their problem, they can also attach an image or video as well to demonstrate the problem.

Created tickets will be displayed on the admin panel in a list. Admin can open any ticket from the list to respond to the corresponding user. Both admin and users can add a comment using the WYSIWYG editor, which helps them to apply styles to their comments. Users and admin can view all the comments from the other person.

The user will receive a notification that a new comment has been added to his ticket and he can respond to admin. Admin can also close the ticket when the issue is resolved. Once the ticket is closed, no-one will be able to add comments on that ticket. The user can also delete the ticket if he wants.

3) Ban & delete user

The third is banning and deleting the user. Banning means that the admin can ban any user he wants, the user’s data will remains to be stored in the database, but the user will not be able to access the system. Once banned, the user will automatically be logged out and when he tries to log in, he will be displayed an error message that he is banned. Admin can unban the user and the user will be able to login now. Admin can also delete the user from the system.

4) Filter bad/abusive words

The fourth is filtering bad words. When the user adds a new post, its content will be checked, and made sure that there are no abusive words in it. If there is any such word, then an error will be displayed and the post will not be saved. The same validation is applied when the post is edited.

5) Adult image validation

The fifth is adult image validation. When the user adds a new post and attaches an image to it, that image is checked and made sure that it must not contain any adult content. If it is an adult image, an error will be displayed and the post will not be saved. Normal images will be uploaded as they were before. The same validation is applied when the post is edited. But if you still do not like any post’s image, you can remove it from the admin panel and it will be removed from the system.

6) Ban post

The sixth is banning the post. When a user posts anything and you find it offensive, instead of deleting it, you can ban the post. So the post will not be removed from the system but it will not be visible to other users. During banning the post, you have to enter the reason to ban. This reason will be visible to the user. The user will get a notification that his post has been banned and he will also see the reason why it is banned. Admin can unban the post and the post will now be visible for everyone.

7) 24 hour stories

You will be able to upload stories that will remain for 24 hours. The stories will be displayed to you and your friends only. After 24 hours, the stories will automatically get deleted using a cron job. You can also delete the story before 24 hours as well. Users will also be able to view all the friends who have seen his story.

8) Audio files

You can upload audio files with the post. You will see the waves of the audio file as well. We are using a library called “wavesurfer” for this.

9) Events

Events are used to inform people about upcoming occasions or festivals. You can create your own events. Or you can mark other’s events if you are going to them.

10) YouTube links

To embed a YouTube video in your post, you simply need to copy the YouTube video URL and paste it into the YouTube pop-up. YouTube videos will be embedded in the post.

11) Advertisement (boost post)

Users can boost their posts by paying a small fee ($1 per day). Boosted posts will be labeled as “Sponsored”. The payment method will be Stripe, so users can pay with their debit or credit card. The boosted post will be displayed on the newsfeed, inbox, groups, and pages.

12) Emoji comments

You can add emojis and smileys while posting a comment. They will be saved in Mongo DB and displayed as emojis.

13) Like, dislike, and comments on stories

You can like, dislike, and add comments to a story shared by your friends. Users can see how many likes and comments they have received on their stories.

14) People nearby

A separate page where you can see a list of all people living in your current city. You can send them a friend request and make your friend circle a little bit bigger.

15) Group chat

You can create groups and each group will have its own QR code. Anyone can scan the QR code and join the group and start chatting.

So these are the 15 major functions we added to the social network project. It is developed in Node JS and Mongo DB.

Video streaming web app in Node JS and Mongo DB, MySQL

This project is available in 2 versions:

  • Node JS and Mongo DB
  • Node JS and MySQL

We created a video streaming web app in Node JS and Mongo DB and also in MySQL.

Features

Authentication

User can create an account using his first name, last name, email and password. Passwords can encrypted so even if your database gets hacked, user’s passwords will not be revealed.

Upload Video

User can upload videos. To upload, he needs to provide a thumbnail of the video as well. Thumbnail will be displayed on home screen, history and search pages. Video will only be played from video detail page. User also needs to enter video title, description, tags, categories and playlist (if any). After video is uploaded, he will be redirected to video edit page where he can edit all these details any time he wants.

I am using a Node JS package called “get-video-duration” to automatically get the duration of video and save it in database. This helps in displaying the duration of video so user will know how long the video is.

My Videos

User can see all his uploaded videos and from there he can edit or delete videos as well.

My Channel

A page from where user can set his profile image, his cover image, can see all his uploaded videos and also he can manage playlists from this page. User can add a playlist and it will be displayed on a list. From the list, he can delete any playlist if he no longer needs. If there is any video in that playlist, then user will see the thumbnail of that video. User will also see the number of videos he has in each playlist.

Home Page

On home page, you will see all uploaded videos by all users in descending order. So you will always see the latest videos on top. Each video in list will have title, duration, categories, the number of views it got and the date when it was uploaded.

Video Detail Page

On video detail page, you can the complete detail of that video. Based on cookies, video view is incremented by 1 when you visit that page. On this page, you will see the complete description of that video and also the user name and profile image who uploaded that video. You can subscribe to that channel if you want, and if you have already subscribed then you can remove that channel from your subscription as well. But you cannot subscribe your own channel.

You can like or dislike a video and you will see the counter incremented or decremented by 1. You can post a comment on a video. When you post a comment, a notification will be sent to the video creator so he knows that a new comment has been posted. Other users can reply to your comment and you will get a notification when someone replied to your comment.

On right side of this page, you will see a section at the top where you can place your Google Adsense code if you want. It will help you monetize your website. Below that, you will see a list of all videos under that playlist.

Search

If you click on any category or tag on video detail page, you will be redirected to a new page where all videos in that category or tag will be displayed. This will help you find the videos of your interest. It’s layout is similar to the one you see on home page.

Watch History

Another page that you can access from left sidebar is “History”. Here you can see a list of all videos that you have played. It will also show you the duration of each video you have viewed. So, for example, if a video is 10 minutes long and you watched 3 minutes 45 seconds of it, then you will see a progress bar that tells you that you your watched duration on this video is 3:45.

This will help you find the video in case you saw a video and now you want to see it again. You can delete the videos from watch history as well.

My Subscriptions

When you subscribe a channel, you will see the number gets incremented. But there should be a page where you can see all the channels you have subscribed and also an option to delete any channel from your subscription. You can see that page from left sidebar on each page.

Settings

User can update his first and last name, and he can also change his password as well if he wants.

Screenshots:

Source code:

Video-streaming-web-app-in-Node-JS-and-Mongo-DB
Video-streaming-web-app-in-Node-JS-and-Mongo-DB

Our TrustPilot reviews

TrustPilot-reviews
TrustPilot-reviews

Check out our single-page chat application developed in Vue JS, Node JS, and Mongo DB.

A blog website with admin panel in Node JS and Mongo DB

We have created a blog website with admin panel in Node JS and Mongo DB. It is designed in Bootstrap. And the view engine is EJS.

Version 1.6

Features:

  1. Create, Read, Update, Delete (CRUD) posts from admin panel
  2. 3 themes (Bootstrap, Clean Blog and Materialize CSS)
  3. Comments and replies
  4. Realtime post add, update and delete
  5. Realtime comments and replies
  6. File manager
  7. Post views counter

File manager

File Manager allows you to manage all your uploaded files in one directory. You can simply go to the admin panel and then “File Manager” from the left sidebar. You can upload new files and you can delete existing files as well. On adding or updating a post, you can simply select the already uploaded file and it will be used in the blog post as featured image.

Views counter

Now you can check how many views your post has got. When someone opens your post, the view counter will be incremented and it can be seen on the post’s detail page.

We are constantly adding more features in this blog website with admin panel developed in Node JS and Mongo DB. Check out our single page chat application developed in Vue JS, Node JS and Mongo DB.