Saturday, October 22, 2016

Send FireBase Push notifications from PHP Application


Recently in one of my project we have mobile applications with PHP web services. In this we have a requirement to send Firebase Push notifications from PHP to mobile app. Here in this blog I am going to explain how to do this.

First all login to your Firebase console and get the Web Api key. Go to and login with your user name and password.

Select your project

Click on gear icons on left and select project settings and above screen will be displayed. Here Web Api Key is the key which you need. copy it. Now let see code one by one.

$url = '';

This is the URL we will use to send push notification.

Now lets build the payload.

$fields = array (
"notification" => array(
"title"=> "Welcome To App",
"body"=> "App Description"

Here to is the filed which contains registration id for the device. This is the id which you get when you register device for push notification.

notification contains title and text to be displayed in notification area. This is a standard format and should not be changed.

data contains all the user defined data you want to send with notification, you can add any number of key value pairs here.

If you don't want to pass any data, remove the data field from payload. So now payload is read now lets encode it to send.

$fields = json_encode ( $fields );

Now send headers with API key.

$headers = array (
'Authorization: key=' . "YOUR_WEB_API_KEY",
'Content-Type: application/json'

Now we will use PHP cURL to send HTTP request.

$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );

$result = curl_exec ( $ch );
echo $result;
curl_close ( $ch );

That's it and Push notification is sent to particular device.

Add Google Place Auto Suggest to Sencha Touch


Recently in one of my project we had a requirement to add Google Place Auto Suggest in Sencha Touch app and I faced certain issue in that so in this blog I am going to explain how to do this.

You can get more information about google place auto suggest from following link.

When you implement it in any web app you will get following result.

As when you start typing it will give you suggestions and you can pick any one suggestion from it.

When we implement same thing with Sencha Touch text field it was working fine. When you start typing suggestions were working but the problem was when user tap to pick one of the suggestion it was not working. It just closes the suggestions and nothing is saved in textfield. There were some solutions like adding some classes and all. I tried everything but it was not working at all. So I came up with different solution. First of all add following textfield in your view.

xtype: 'panel',
xtype: 'textfield',
itemId: 'autoSuggest',
id: 'autoSuggest',
height: 10,
inputCls:'x-input-el x-form-field x-input-text grey-input',
name: 'address',
allowBlank: false,
autoCapitalize: false,
clearIcon: false

Now bind key up event for this textfield in your controller.

'#autoSuggest': {
keyup: 'onSearchAddressTap'

Now our logic is the query Google place API manually and store result in Data Store and show it in dataview. So we will need model and store.

Following is our model.

Ext.define('MYAPP.model.AddressSuggestion', {
    extend: '',
    config: {
        fields: [
            { name: "description", type: 'string' }


And Following is our store.

        model: 'MYAPP.model.AddressSuggestion',
        autoLoad: true,
            type: 'memory'

Now lets key up event.

onSearchAddressTap: function(textField){
if(textField.getValue().length > 3){
url : ''+textField.getValue()+'&types=geocode&language=fr&key=YOURKEY',

scope : this,
//method to call when the request is successful
var result = Ext.decode(response.responseText);
for(var i =0;i



So as you can see above we are sending an Ajax request to google maps api and store result in Datastore. 

Now add following dataview in your view just below the above textfield.

xtype: 'panel',
flex: '1',
layout: 'fit',
items: [
xtype   : 'dataview',
margin: '0 20 0 20',
itemId: 'venueAddress',
id: 'venueAddress',
'<table style="border-bottom: 1px solid #e3e3e3;"><tr><td style="padding-bottom: 12px;padding-top: 12px;width:95%"><div style="color:#262626;font-size: 15px">{description}</div></td><td><img width="40" height="40" src="resources/images/howMuchSpace.png" /></td></td></tr></table>'
store: 'AddressSuggestion'


So now as soon as you start typing you will get result filled up in dataview and then add itemtap event of dataview and get the selected address and hide the dataview.

onVenueAddressItemTap: function(list, index, target, record, e){

Ultimate output is like following.

Hope this helps you.

Saturday, October 15, 2016

Sencha Touch Hide Pickers on Android Back Key Press


I recently published an article about hiding sencha touch Message box on press of back button in android. You can read it here Sencha Touch Hide Alert Box on Android Back Button Press

This post is something similar to it. Recently we created an android application with Sencha Touch and Cordova for client. After testing, client came up with requirement that if any picker is open for example calendar picker or select field picker etc. It should be closed on press of back button in android. So after efforts of half an hour, I found a solution. 

In Sencha Touch pickers are basically floating panels. So what we have to do it get all the floating panels and see if it's hidden or not. If not hidden then hide it.

First of all you have to bind back button event of android using cordova. Please check this cordova document on how to do this here.

Once you add backbutton listener, add following code.

var floatingComponents = Ext.query('.x-floating');
for(var i=0;i
var component = Ext.getCmp(floatingComponents[i].id);
if(component.isHidden() == false){

As you can see in above code, first we are finding all the floating component using Ext.query and class x-flaoting

Then we loop through it and find component using id of floating component and check if component is not hidden then hide it and return from there. 

Hope this helps you.

Saturday, October 1, 2016

Android Adding Button Click Action In Notification Bar


Recently in one of my project we have a requirement to add button in notification area and do some actions when button is clicked. So here in this blog I am going to explain how to do this.

First of all Add following XML file in your layout and name it as custom_notification. This will have definition for button we are going to add in notification bar.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
    android:orientation="vertical" >

        android:text="Click Me"


Now in your MainActivity add following function and call it in onCreate method to create notification with button.

public void createNotificationInNotificationBar(){
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, "Click Me To Do Some Action", when);

NotificationManager mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
contentView = new RemoteViews(getPackageName(), R.layout.custom_notification);
notification.contentView = contentView;
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
notification.flags |= Notification.FLAG_NO_CLEAR; //Do not clear the notification

Above code will create notification with button. User will not be able to clear this notification. Now we will add click action handler to button. Add following lines at end of above function.

Intent myIntent = new Intent("button_clicked");
PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
contentView.setOnClickPendingIntent( myButton, 

Now add following code to your Manifest.xml file.

This will create receiver and action. Now add receiver to your main activity.

public static class RecordShareReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context.getApplicationContext(), ButtonClickActivity.class);

This will start ButtonClickActivity. 

public class ButtonClickActivity extends Activity{
public void onCreate(Bundle savedInstanceState)
//Do your actions here

As you can see in above in onCreate method you can do the actions as per your requirement. Once the action is done we finish activity.

Add following code to your android manifest for activity.

android:name=". ButtonClickActivity" 
android:theme="@android:style/Theme.Translucent.NoTitleBar" />

As you can see above we set theme as Translucent theme so activity will not be visible. It will just start do the action and gets finished. 

Laravel 5.x Store Uploaded Files to Amazon S3

Recently in one of my Laravel 5.2 project, we used Amazon s3 to store static files and user uploaded files. So here in this blog I am going to explain how to do this.

1) First of all install following plugin through composer.

composer require league/flysystem-aws-s3-v3 ~1.0

2) Now add your S3 credentials to your environment (.env file)


3) Open config.filesystems.php and configure s3 driver as follow.

's3' => [
            'driver' => 's3',
            'key'    => env('S3_KEY'),
            'secret' => env('S3_SECRET'),
            'region' => env('S3_REGION'),y.
            'bucket' => env('S3_BUCKET'),

4) Now open controller where you have code to manage uploaded file and add following dependency.

use Illuminate\Contracts\Filesystem\Filesystem;

5) Use following code to store your file to S3.

$image = $request->file('user_uploaded_image');
$imageFileName = time() . '.' . $image->getClientOriginalExtension();
$s3 = \Storage::disk('s3');
$filePath = '/mypath'/.$imageFileName;
$s3->put($filePath, file_get_contents($image), 'public');
$uploadedFileS3Path = 'https://'.env('S3_BUCKET').'/'.$filePath;

Please note in my case I configured S3 bucket to be direct URL of uploaded file. In case your case if you have not configured it then your path will be as follow.

$uploadedFileS3Path = 'http://s3-'.env('S3_REGION').''.env('S3_BUCKET').'/'.$filePath;

This path you can use to display file and you can store it to database as well.

Special Case 

If you are using it in localhost using XAMPP in your windows system. You have to do following few steps.

Download certificate pem file from this link. and store it to some where in your C drive or whatever drive you have your xampp installed.

For example I put it in  C:\code\cacert.pem

Now open your php.ini file and bottom of the file add following line.

curl.cainfo = C:\code\cacert.pem

That's it and it will work in your local environment too. Hope this helps you.

Sunday, September 25, 2016

Sencha Touch Hide Alert Box on Android Back Button Press


Recently in one my project our client gave use very strange requirement. We have used Sencha Touch to create application and used Cordova to create native app.

As we all know with Sencha Touch we use Ext.Msg.alert() to show user alert. This alert has OK button. When user tap on that alert goes away.

However in our case client asked us to hide this alert if its on and user presses virtual or physical hardware button of android phone. So after hearing this requirement first of I was confused and was not sure how to implement it. But after looking at docs and source code of Ext.Msg class solution was very easy so on this blog I am going to explain how to do this.

First of all we have to bind back button key event. Add following code to your app.js file.

if ('Android')) {
            document.addEventListener("backbutton", Ext.bind(onBackKeyDown, this), false);
            function onBackKeyDown(e) {

Now as we all know Ext.Msg is singleton class and the alerts and confirm boxes are nothing but a floating panels. So we can just simply check if it's hidden or not and hide it if required. Check the following code.

if ('Android')) {
            document.addEventListener("backbutton", Ext.bind(onBackKeyDown, this), false);
            function onBackKeyDown(e) {
                     if(Ext.Msg.isHidden() !=  null){
                             if(Ext.Msg.isHidden() == false){
                             var comp = Ext.getCmp("ext-sheet-1");

As you can see in above code. First we are checking Ext.Msg.isHidden() !=  null, this is to check if there is no instance of alert is created yet, there is no meaning of hiding it.

Then we check if Ext.Msg.isHidden() == false then just hide it or else don't do anything. That's it. Hope this helps you.

Cordova Applicaiton Select Any File From SD Card and Upload to Server


Recently in one of my project we were building android application with Cordova. There was a requirement where user can choose any files from SD card and upload it to server.

So in this blog I am going to explain how to do this.

Our challenges was user can pick any file like audio, video, image, pdf etc. So we have to properly save it on server with proper extension.

First of all you will need two plugins.

1) Cordova File Transfer Plugin

You can install it via following command.

cordova plugin add cordova-plugin-file-transfer

2) File Chooser Plugin

You can check this plugin here and can install it via following command.

cordova plugin add

Now once you install file choose plugin you can use following command to open file selector in android. {

Now the problem with this file chooser plugin is that it gives content path like this.


However this path can not be used with File Transfer Plugin as it needs absolute file URI like this.


So we have to edit this file chooser plugin little bit. Go to your android project and open file from the com.megster.cordova package and check the following function.

public void onActivityResult(int requestCode, int resultCode, Intent data) {


See the following line of code in this function.

Uri uri = data.getData();


So form here it returns the content path.

We have to convert that content path to absolute path. So add following functions in

public static String getPath(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];

                // TODO handle non-primary volumes
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] {

                return getDataColumn(context, contentUri, selection, selectionArgs);
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();

        return null;

     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     * @param context The context.
     * @param uri The Uri to query.
     * @param selection (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
    public static String getDataColumn(Context context, Uri uri, String selection,
            String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
            if (cursor != null && cursor.moveToFirst()) {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
        } finally {
            if (cursor != null)
        return null;

     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
    public static boolean isExternalStorageDocument(Uri uri) {
        return "".equals(uri.getAuthority());

     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
    public static boolean isDownloadsDocument(Uri uri) {
        return "".equals(uri.getAuthority());

     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
    public static boolean isMediaDocument(Uri uri) {
        return "".equals(uri.getAuthority());


Now update onActivityResult function as follow.

callback.success(getPath(cordova.getActivity(), uri));

It will send you correct absolute URI.  Now in your JavaScript.

var filePath = '';
var fileType = ''; {
            filePath = 'file://'+obj;
            fileType= obj.substring(uri.lastIndexOf('.'));

As you see above we are storing file path and file extension in two variables. Now following is the code to upload your file to server.

        var win = function (r) {
                alert('file uploaded');

        var fail = function (error) {

        var options = new FileUploadOptions();
        options.fileKey = "file";
        options.fileName = filePath.substr(this.evidencePath.lastIndexOf('/') + 1);
        options.mimeType = "text/plain";

        var params = {};
        params.fileType = fileType;
        options.params = params;

        var ft = new FileTransfer();
        ft.upload(filePath, encodeURI("http://yourserverpath"), win, fail, options);

On the server side your PHP code should be as follow.

$file_type = $_POST['fileType'];
$fileName = time()."_".$file_type;
move_uploaded_file($_FILES["file"]["tmp_name"], "/yourserverpath/".$fileName);
return json_encode(array('success'=>true,'index'=>$index, 'server_path'=>"http://serverpath".$fileName));

That's it, hope this helps you.