I have a news website based on WordPress, I send notifications using OneSignal plugin, recently I created Android webview app, the notifications received on mobiles when clicked the article open in a browser instead of the App itself.
According to OneSignal documentation, I should create a most used plugin file "mu-plugin" including this PHP functions :
<?php
add_filter('onesignal_send_notification', 'onesignal_send_notification_filter', 10, 4);
function onesignal_send_notification_filter($fields, $new_status, $old_status, $post) {
/* Goal: We don't want to modify the original $fields array, because we want the original web push notification to go out unmodified. However, we want to send an additional notification to Android and iOS devices with an additionalData property.
* */
$fields_dup = $fields;
$fields_dup['isAndroid'] = true;
$fields_dup['isIos'] = true;
$fields_dup['isAnyWeb'] = true;
$fields_dup['isWP'] = false;
$fields_dup['isAdm'] = false;
$fields_dup['isChrome'] = false;
// $fields_dup['android_channel_id'] = "<CHANNEL ID UUID HERE>";
$fields_dup['data'] = array("myappurl" => $fields['url']);
/* Important to set web_url to support opening through both mobile and browser*/
$fields_dup['web_url'] = $fields_dup['url'];
/* Important to unset the URL to prevent opening the browser when the notification is clicked for mobile app users */
unset($fields_dup['url']);
$onesignal_post_url = "https://onesignal.com/api/v1/notifications";
/* Hopefully OneSignal::get_onesignal_settings(); can be called outside of the plugin */
$onesignal_wp_settings = OneSignal::get_onesignal_settings();
$onesignal_auth_key = $onesignal_wp_settings['app_rest_api_key'];
$request = array("headers" => array("content-type" => "application/json;charset=utf-8", "Authorization" => "Basic " . $onesignal_auth_key), "body" => json_encode($fields_dup), "timeout" => 60);
$response = wp_remote_post($onesignal_post_url, $request);
if (is_wp_error($response) || !is_array($response) || !isset($response['body'])) {
$status = $response->get_error_code();
$error_message = $response->get_error_message();
error_log("There was a " . $status . " error returned from OneSignal when sending to mobile users: " . $error_message);
return;
}
return $fields;
}
?>
Now the notification open up the mobile app instead of browser, but showing the home page instead of the article it self.
Note: If I use OneSignal dashboard to send notification, and I unset the "Launch URL", then add in "Additional Data" the following fields :
Key : URL
Value : The post url
Then the notification will open the mobile app with deep linking to the article page.
Anyone can help me modify the function ?
Thanks :)
Related
I am using firebase dynamic link in my react native mobile application, everything is working well as I want.
One thing I am not able to implement that is, I have created one HTML preview page to show preview on other social media. I have set fallback url for iOS, android. when I share that link it works well in android and iOS , when user not installed app then it redirect to my website page. But in computer when I hit that it not redirect me to my website page it open only preview page which I am passing in link parameter.
If I am use
otherPlatform:{
fallbackUrl:DEEPLINK_FALLBACK
}
Then it works but the preview not show the by default preview is showing of fallbackUrl url of OtherPlatform.
This is the complete code I am using to generate dynamic link in my react native app.
const buildVideoLink = async () => {
try {
const activityId = selectedPozzle?.activityId ? selectedPozzle?.activityId : ""
const pozzleId = selectedPozzle?.pozzleId ? selectedPozzle?.pozzleId : ""
const conentLink = FEED_PREVIEW_URL + pozzleId + "/preview/"
const link = await dynamicLinks().buildShortLink({
link: conentLink + "?activityId="+activityId+"&pozzleId=" + pozzleId,
domainUriPrefix: DEEPLINK_DOMAIN,
otherPlatform:{
fallbackUrl:DEEPLINK_FALLBACK
},
android: {
packageName: ANDROID_PACKAGE,
fallbackUrl:DEEPLINK_FALLBACK,
},
ios: {
appStoreId: '12345678',
bundleId: IOS_BUNDLE,
fallbackUrl:DEEPLINK_FALLBACK,
}
}
);
console.log("Pozzle_share_link........", link)
return link;
}
catch (error) {
}
}
I am trying to integrate the Square Payment on my Ionic 1 application using the Web API based on their docs here. They are using intent anchor to call the Square app and send appropriate payment details. But when I tried to implement, it gives me this error:
Can't display PDF file (intent URL cannot be opened)
Here's my code snippet:
var hrefString = 'intent://#Intent;';
var extrasObject = { /* extras */
"action": "com.squareup.register.action.CHARGE",
"package":"com.squareup",
"S.browser_fallback_url":"<my-fallback-url>",
"S.com.squareup.register.CLIENT_ID":"<my-client-id>",
"S.com.squareup.register.WEB_CALLBACK_URI": "<registered-callback-uri>",
"S.com.squareup.register.API_VERSION":"v1.3",
"i.com.squareup.register.TOTAL_AMOUNT": 100,
"S.com.squareup.register.CURRENCY_CODE":"USD",
"S.com.squareup.register.TENDER_TYPES":"com.squareup.register.TENDER_CARD,com.squareup.register.TENDER_CARD_ON_FILE,com.squareup.register.TENDER_CASH,com.squareup.register.TENDER_OTHER"
};
// Generate intent anchor
for(var key in extrasObject) {
hrefString += key + '=' + extrasObject[key] + ';';
}
// Convert string to URI
var intentURL = encodeURIComponent(hrefString + 'end');
window.open(intentURL, "_system", "location=no");
Prior to this implementation, I already install the InAppBrowser Cordova plugin here.
Can someone help me on this one? Thanks in advance!
I am trying to use Google OAuth2 for Google Drive authentication on both Android and iOS. I had a solution working on Android using ChildBrowser, but it did not work on iOS. PhoneGap Build support suggested I use InAppBrowser because ChildBrowser is depreciated.
I can get iOS and Android both to prompt my user for ID/PW then it shows "Allow Access" button all in InAppBrowser to give Googl Drive access. On Android tapping Allow Access button gives page not available error with correct code and OAuth token in the url. When using childbrowser it was this change event that allowed you to check for code 4 and get the token. InAppBrowser only has LoadStart, LoadStop and Exit events.
How can I check the Google return URL for success/failure and if success grab the token?
Thanks for any and all help!
Here's how I use InAppBrowser to do Facebook auth. Since you're just trying to grab a value out of the url, it should work the same way:
var fb = {
id: '...'
,secret: '...'
,namespace: '...'
,redirect: '...'
,display: 'touch'
,scope: ['publish_actions']
,windowRef: null
,code: null
,onLoadEvent: function(event){
var url = event.url;
console.log(url);
//once we've been redirected to this domain, fb's job is done
if (/my.domain.com/.test(url)){
if (/code=/.test(url)){
//auth done
var code = url.match(/code=([^\&]+)/)
if (code) code = code[1];
window.fb.code = code;
window.fb.windowRef.close();
}else if (/error_description=/.test(url)){
//login unsuccessful
var error = url.match(/error_description=([^\&]+)/);
if (error) error = error[1].replace(/[^A-Z0-9 ]/gi, " ");
console.error("facebook login failed: " + error);
window.fb.code = null;
window.fb.windowRef.close();
}
}
}
};
var authUrl = "https://graph.facebook.com/oauth/authorize?"
+ "client_id=" + fb.id
+ "&redirect_uri=" + encodeURI(fb.redirect)
+ "&display=" + fb.display
+ "&scope=" + fb.scope.join('%2C');
fb.windowRef = window.open(authUrl, '_blank', loginPopupOptions);
//no reason we can't use the same function twice...
fb.windowRef.addEventListener('loadstart', fb.onLoadEvent);
fb.windowRef.addEventListener('loadstop', fb.onLoadEvent);
I tried to pull only the relevant bits out of our structure so hopefully it makes sense this way...
Is it possible to communicate an android Application with cakePhp website and share data? If it is possible, I want to create an application that can login into the website; my doubt is:
How to pass user name and password from our application to cakephp websites login page? Can anybody show me an example program?
How cakephp controller handle this request and respond to this request? Please show me an example program?
(I am a beginner in android and cakephp.)
Quick answer -- YES!
We just finished pushing an Android app to the market place that does this exact thing. Here's how we did it:
1) Download and learn to use Cordova PhoneGap (2.2.0 is the latest version) within Eclipse. This makes the whole thing so much easier with just some HTML and a lot of Javascript.
2) In your JS, create methods that push the login information using AJAX parameters. Example:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
$("#login").click(function() {
$email = $("#UserEmail").val();
$pass = $("#UserPassword").val();
$.ajax({
url : yourURL + 'api/users/login',
async : false,
data : {
'email' : $email,
'password' : $pass
},
dataType : 'json',
type : 'post',
success : function(result) {
/**
* do your login redirects or
* use localStorage to store your data
* on the phone. Keep in mind the limitations of
* per domain localStorage of 5MB
*/
// you are officially "logged in"
window.location.href = "yourUrl.html";
return;
},
error : function(xhr, status, err) {
// do your stuff when the login fails
}
});
}
}
3) In Cake / PHP, your Users controller here will take the username and password data in the AJAX call and use that for its authentication.
<?php
class UsersController extends AppController {
public $name = 'Users';
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('api_login');
}
public function api_login() {
$this->autoRender = false;
if ($this->request->data && isset($this->request->data['email']) && isset($this->request->data['password'])) {
$arrUser = $this->User->find('all',array(
'conditions'=>array(
'email'=> $this->request->data['email'],
'password' => $this->Auth->password($this->request->data['password']),
)
)
);
if (count($arrUser) > 0) {
$this->Session->write('Auth.User',$arrUser[0]['User']);
// Do your login functions
$arrReturn['status'] = 'SUCCESS';
$arrReturn['data'] = array( 'loginSuccess' => 1,'user_id' => $arrUser[0]['User']['id'] );
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
echo json_encode($arrReturn);
}
}
?>
That's pretty much it. You are now authenticated to CakePHP.
You do not need to use "api_", you can use any function name you want, but this helped us keep a handle on what we allowed mobile users to do versus web users.
Now, these are just the building blocks. You basically have to create a whole version of your site on the phone using HTML and Javascript, so depending on your application it may be easier just to create a responsive design to your site and allow mobile browsing.
HTH!
Use Admad JWT Auth Plugin
If you use cakephp3 change your login function with this one :
public function token() {
$user = $this->Auth->identify();
if (!$user) {
throw new UnauthorizedException('Invalid username (email) or password');
}
$this->set([
'success' => true,
'data' => [
'token' => JWT::encode([
'sub' => $user['id'],
'exp' => time() + 604800
],
Security::salt())
],
'_serialize' => ['success', 'data']
]);
}
You can read this tutorial about REST Api and JWT Auth Implementation
http://www.bravo-kernel.com/2015/04/how-to-add-jwt-authentication-to-a-cakephp-3-rest-api/
if rebuild most of the view pages in cakephp into ajax will seem defeat the purposes of using cakephp as it is.
I really need your help. I am junior Joomla! developer and also junior Android developer. I am currently building an Android app for Joomla! site administration. So, where do I need help?
I managed without any problems to log in some user to frontend using this code:
// Function for user login
// return : JSON array (login : true/false; user_id : if user is loged in)
public function login() {
$post = JFactory::getApplication()->input;
$result = array();
$username = $post->get('username');
$password = $post->get('password');
$credentials = array("username" => $username, "password" => $password);
$app = JFactory::getApplication('site');
$result['login'] = $app->login($credentials);
if($result['login']) {
$result['user_id'] = JUserHelper::getUserId($username);
}
CJoomDroidHelper::postResult($result);
}
I made component named CJoomDroid which is simple web service with JSON response for every call.
For an example, when I enter:
http://some.joomla.website/index.php?option=com_cjoomdroid&view=authetication&task=login&username=user&password=pass&format=raw
, I manage to log in user to front site panel.
So no problems there, but if I want to log in to administration panel with same user using this code:
// Function for user login
// return : JSON array (login : true/false; user_id : if user is loged in)
public function login() {
$post = JFactory::getApplication()->input;
$result = array();
$username = $post->get('username');
$password = $post->get('password');
$credentials = array("username" => $username, "password" => $password);
$app = JFactory::getApplication('admin');
$result['login'] = $app->login($credentials);
if($result['login']) {
$result['user_id'] = JUserHelper::getUserId($username);
}
CJoomDroidHelper::postResult($result);
}
On this link:
http://some.joomla.website/administration/index.php?option=com_cjoomdroid&view=authetication&task=login&username=user&password=pass&format=raw
, I am getting errors. Is there any way to log in to admin panel this way?
Thanks!
Errors are like "Your session has expired; Please log in again.." etc... Android app is making call with: HttpResponse response = httpclient.execute(new HttpGet(url.toString())); , and response should be JSON object like:
{"login":true}
Automatically logging on Joomla can be very tricky.
You should give a look to this post on google groups.
There is a library named FrameworkOnFramework that enhance the power of Joomla and allows you to automatically login (via CLI or using a simple call) providing a very good protection.