Monday, August 7, 2017

Integrating GetStream with Laravel using stream-laravel for Real Time Notifications

Hello,

After a long time I am publishing a blog post. I am sorry to all my readers for not publishing blog for longer time. In this blog I am going to explain how you can have real time notifications in your laravel application using GetStream.io.

I will not go in installation details as it's very well documented on their Github page. You can refer it here.

GetStream/steam-laravel

After you have installed it and configured service provider. First thing you have to do is create table for notifications. For that create migration add following code to it.

Schema::create('notifications', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->index();
$table->string('name');
$table->string('message');
$table->string('link');
$table->timestamps();
});

Now create a model with name Notifications and add following code to it.


namespace App\Http\Models;

use App\User;
use Illuminate\Database\Eloquent\Model;

class Notifications extends Model
{
    //
    use \GetStream\StreamLaravel\Eloquent\ActivityTrait;
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $table = 'notifications';

    protected $fillable = ['name', 'message','link'];
   
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'user_id' => 'int',
    ];
    /**
     * Get the user that owns the task.
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
    /**
     * Stream: Add extra activity data - task name, and user's display name:
     */
    public function activityExtraData()
    {
        return array('name'=>$this->name, 'message' => $this->message, 'link'=> $this->link);
    }
   /**
    * Stream: Change activity verb to 'created':
    */
    public function activityVerb()
    {
        return 'created';
    }

}


Now open your user model and add following code to it.

public function notifications()
    {
        return $this->hasMany(Notifications::class);
    }

So now we have notifications table setup and it's linked to user with hasMany relationship. Now next we will show how you can create notification.

$userObject->notifications()->create([
'name' => "NOTIFICATION_NAME",
'message' => 'NOTIFICATION_MESSAGE',
'link' => 'NOTIFICATION_LINK'           
]);

Here userObject is the object of user for whom you want to create notification. Now next we will show how to get all the notifications and show it user. For this we are going to use AngularJs. 

We are using client side library of GetStream.io you can download it from following link.


For this first of all we have to get token and that can be generated only from server side code. So create an API and call it from AngularJs controller. Here is the API code.

public function getStreamToken(){
$feed = \FeedManager::getUserFeed(Auth::user()->id);
$token = $feed->getToken();

return Response::json(array("success"=>true,"token"=>$token,"user_id"=>Auth::user()->id));
}

Now as soon as we get token, next you have to connect to client and get user feeds and register for push notifications. Here is the code for the same.

var client = stream.connect('YOUR_API_KEY', null, 'YOUR_APP_ID');
$scope.user = client.feed('user', $scope.user_id, $scope.token);

function successCallback() {
console.log('now listening to changes in realtime');
}

function failCallback(data) {
console.log(data);
}

$scope.user.subscribe($scope.gotNotification).then(successCallback, failCallback);    

$scope.user.get({limit:10, offset:$scope.offset}, $scope.gotUserActivities);

So above code will register you for the push notification and will get all your notifications. Now you have to display it using HTML and CSS as per your wish. 

For showing new notification, you can use below code in gotNotification function.

$.bootstrapGrowl(data.new[0].name + ' ' + data.new[0].message, { type: 'success' });

It will show nice pop up on screen.