Saturday, October 22, 2016

Send FireBase Push notifications from PHP Application

Hello,

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 https://console.firebase.google.com/ 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 = 'https://fcm.googleapis.com/fcm/send';

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

Now lets build the payload.

$fields = array (
'to' => 'REGISTRATION_KEY',
"notification" => array(
"title"=> "Welcome To App",
"body"=> "App Description"
),
"data"=>array(
"key_1"=>"value_1",
                        "key_2"=>"value_2"
)
);

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

Hello,

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.

https://developers.google.com/places/web-service/autocomplete

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',
flex:'1',
items:[
{
xtype: 'textfield',
placeHolder: 'TYPE IN THE CITY OR THE ADDRESS',
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: 'Ext.data.Model',
    config: {
        fields: [
            { name: "description", type: 'string' }

        ]
    }
});

And Following is our store.


Ext.define('MYAPP.store.AddressSuggestion',{
    extend:'Ext.data.Store',
    config:{
        model: 'MYAPP.model.AddressSuggestion',
        autoLoad: true,
        proxy:{
            type: 'memory'
        }
    }
});

Now lets key up event.

onSearchAddressTap: function(textField){
Ext.getStore('AddressSuggestion').removeAll();
if(textField.getValue().length > 3){
this.getVenueAddress().show();
Ext.Ajax.request({
url : 'https://maps.googleapis.com/maps/api/place/autocomplete/json?input='+textField.getValue()+'&types=geocode&language=fr&key=YOURKEY',

scope : this,
//method to call when the request is successful
success:function(response,opts)
{
var result = Ext.decode(response.responseText);
for(var i =0;i
Ext.getStore('AddressSuggestion').add({'description':result.predictions[i].description});
}
console.log(result);
},

failure:function(err)
{

}
});
}
}

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',
itemTpl:
[
'<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){
this.getAutoSuggest().setValue(record.get('description'));
this.getVenueAddress().hide();
}

Ultimate output is like following.



Hope this helps you.

Saturday, October 15, 2016

Sencha Touch Hide Pickers on Android Back Key Press

Hello,

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){
if(component.isHidden() == false){
component.hide();
return;
}
}
}

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

Hello,

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="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:gravity="center_vertical"
    android:orientation="vertical" >

<Button 
        android:id="@+id/myButton" 
        android:layout_width="wrap_content" 
        android:layout_height="40sp" 
        android:layout_weight="1" 
        android:text="Click Me"
        android:textColor="#000000"
        android:textSize="10sp">
    </Button>


</LinearLayout>

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(R.id. myButton, 
                pendingSwitchIntent);

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 {
@Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context.getApplicationContext(), ButtonClickActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}


This will start ButtonClickActivity. 

public class ButtonClickActivity extends Activity{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Do your actions here
finish();
}
}

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:label="@string/app_name" 
android:launchMode="singleTask" 
android:name=". ButtonClickActivity" 
android:screenOrientation="portrait" 
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)

S3_KEY=YOUR_KEY
S3_SECRET=YOUR_SECRET
S3_REGION=YOUR_REGION
S3_BUCKET=YOUR_BUCKET

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').'.amazonaws.com/'.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. https://curl.haxx.se/ca/cacert.pem 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.