When the user visits the mobile website via android/ios iphone, it should be redirected respective apps in their phone. If they still didn't install the respective apps for the websites, they should be redirected to respective apps in play store or apple store. Inside App.vue file below changes are done.
const userAgent = window.navigator.userAgent;
const isIphone = userAgent.match(/iPhone/);
const isAndroid = userAgent.match(/Android/);
const isIpad = userAgent.match(/iPad/);
beforeCreate: function() {
if ((isIphone === "iPhone" || isAndroid === "Android") && isIpad === "null") {
window.location = `{yourApp}:///`;
}
},
created: function() {
if (isIphone || isAndroid) {
setTimeout(() => {
if (isIphone === "iPhone") {
window.location.href = "https://apps.apple.com/app/id{<app id>}"; //here add your correct app id
} else if (isAndroid === "Android") {
window.location.href =
"https://play.google.com/store/apps/details?id=<app id>"; //here add your correct app id
}
}, 2500);
}
}
But it won't work as I expected. I guess reason could be device identification issue. Anyone knows how to solve this issue or any other approach to do deep linking in vue js?
userAgent.match() will return an Array type. Then in beforeCreate hook you're checking if those consts are strings, but they are arrays possibly carrying those strings inside them. You also perform similar checks in the created hook. That is probably why your statements never execute.
Related
Note: Total Ionic newbie here.
I have the following:
Ionic 5 (Capacitor) app with Angular 11.
Express backend (localhost:3000)
I can fetch data from an API call and display in the browser, but not on the emulated Android device. I don't know how to check for console errors in Android Studio.
This image can explain the situation better.
I think this is due to CORS. I tried to follow the Ionic page on this but no resolution.
Here is my Express code:
const express = require("express");
const cors = require("cors");
const app = express();
const port = 3000;
const allowedOrigins = [
"capacitor://localhost",
"ionic://localhost",
"http://localhost",
"http://localhost:8080",
"http://localhost:8100",
"http://192.168.2.25:8100",
];
// For parsing JSON in request body
app.use(express.json());
// MySQL connection details - for POC sake.
// In PROD, these are typically saved in .env variables
// Ref: https://www.linkedin.com/pulse/storing-database-credentials-securely-siddhesh-jog
var mysql = require("mysql");
var connection = mysql.createConnection({
host: "____________________________.us-east-2.rds.amazonaws.com",
user: "admin",
password: "*****************",
database: "poc",
});
const corsOptions = {
origin: (origin, callback) => {
if (allowedOrigins.includes(origin) || !origin) {
callback(null, true);
} else {
console.log(origin);
callback(new Error("Origin not allowed by CORS"));
}
},
};
// Enable preflight requests for all routes
app.options("*", cors(corsOptions));
// Connect to MySQL
connection.connect(function (err) {
if (err) throw err;
console.log("Connected!");
});
// Dashboard - GET
app.get("/dashboard", cors(corsOptions), (req, res) => {
rows = [];
connection.query(
"select label_id, value from poc_fct",
function (err, result) {
if (err) throw err;
res.json(result);
}
);
});
app.listen(port, () => {
console.log(`CORS-enabled web server listening at http://localhost:${port}`);
});
Any help will be greatly appreciated.
What finally worked for me was changing the API endpoint from http://localhost:3000/data to http://192.168.2.25:3000/data, where 192.168.2.25 is the local IP address of the host where the Express server is running.
Few notes for anyone else who might have this issue in the future:
This isn't a CORS issue. I commented out app.use(cors)
This isn't a HTTP/HTTPS issue
Changing the emulator's proxy to 10.0.2.2:3000 did not work
I want to integrate Stripe 3d secure in my react native app. Using this lib: https://github.com/tipsi/tipsi-stripe, and with simple payment it works well. But with 3D I have several problem on iOS and also on Android:
iOS: createCardSource: true (at line 7 crashing the app).(Solved)
iOS: Stucked before redirection on the secure page
Android: How I know if the user paid or decline the payment at the remote page?(At line 27 no any data in the secure3dSourceResponse object)
import stripe from "tipsi-stripe";
paymentRequest = async (mutation, deal) => {
let paymentRequest;
try {
paymentRequest = await stripe.paymentRequestWithCardForm({
...options,
createCardSource: true
});
//iOS and Android gets back different objects.
const threeDSecure = Platform.OS === "android"
? paymentRequest.card.three_d_secure
: paymentRequest.details.three_d_secure;
if (
threeDSecure === "recommended"
|| threeDSecure === "required"
) {
let prefix = Platform.OS === "android"
? `appName://appName/`
: `appName://`;
let secure3dSourceResponse = null;
try {
const { dealFeeUSD } = this.state;
// On iOS the process stucked here, without any error message
secure3dSourceResponse = await stripe.createSourceWithParams({
type: "threeDSecure",
amount: dealFeeUSD || 3000,
currency: "USD",
flow: "redirect",
returnURL: prefix,
card: paymentRequest.sourceId
});
// On android I have no any data in secure3dSourceResponse after Stripe returns from their page.
} catch (error) {
console.log('secure3dSourceResponse', secure3dSourceResponse)
}
} else {
if (paymentRequest && paymentRequest.tokenId) {
this.handlePayDeal(mutation, deal, paymentRequest.tokenId);
}
}
} catch (error) {
console.log("paymentRequest: " + JSON.stringify(error));
}
};
I've saved the file i want to share locally using FileSystem.downloadAsync
Share.share works fine for iOS. How can I share an image I have saved locally on Android?
I've tried
https://github.com/lucasferreira/react-native-send-intent
https://github.com/react-native-community/react-native-share
Both these solutions do not seem to work with Expo.
I'm using react-native version : https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz
FileSystem.downloadAsync(url, FileSystem.documentDirectory+filename).then(({uri})=>{
if(Platform.OS == "android"){
// ???
}
else{
Share.share({url:uri});
}
})
Is there something i'm missing?
Since SDK33, you can use Expo Sharing to share any type of file to other apps that can handle its file type even if you're on Android.
See : https://docs.expo.io/versions/latest/sdk/sharing/
Usage is pretty simple :
import * as Sharing from 'expo-sharing'; // Import the library
Sharing.shareAsync(url) // And share your file !
In order for users to share content saved within our (Expo) app, we structured it like this. (This is working across iOS & Android).
IMPORT SHARING:
import * as FileSystem from 'expo-file-system';
import * as Sharing from 'expo-sharing';
ADD ONPRESS TO BUTTON (OR WHEREVER):
<Button
name="share"
onPress={() =>
openShareDialogAsync(media, {
video: media.meta.fileType === 'video',
})
}
/>
SHARE VIDEO OR IMAGE TO ANY APP IN USERS HANDSET
const openShareDialogAsync = async (mediaProp, options) => {
const fileDetails = {
extension: options.video ? '.mp4' : '.jpg',
shareOptions: {
mimeType: options.video ? 'video/mp4' : 'image/jpeg',
dialosTitle: options.video
? 'Check out this video!'
: 'Check out this image!',
UTI: options.video ? 'video/mp4' : 'image/jpeg',
},
};
const downloadPath = `${FileSystem.cacheDirectory}${mediaProp.media_id}${fileDetails.extension}`;
const { uri: localUrl } = await FileSystem.downloadAsync(
mediaProp.url,
downloadPath
);
if (!(await Sharing.isAvailableAsync())) {
showMessage({
message: 'Sharing is not available',
description: 'Your device does not allow sharing',
type: 'danger',
});
return;
}
await Sharing.shareAsync(localUrl, fileDetails.shareOptions);
};
Hope this helps :]
I am building an app that is using Google authentication through firebase and that needs to redirect the user from a login.vue component to an /hello path upon successful authentication.
I have first tried doing it the normal vue way:
this.$router.replace('/hello')
only to realise my Samsung Galaxy J5 wasn't having it...
All is working on other devices and browsers (so far) using the normal Vue routing tools but on some Android devices Vue is refusing to collaborate. I have read here some Android versions do not like the way the Vue dynamic routing transpiles to vanilla JS so I am attempting the following (still, no success).
This is my code on the created hook of component login.vue when Google auth (with redirection, not pop up) returns to it:
created() {
firebase.auth().getRedirectResult().then(result => {
var user = result.user;
if (user) {
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("android") > -1;
if(isAndroid) { // NOT WORKING (stays on Login.vue although I am sure it's detecting it's an Android)
window.location.href = window.location.host + '/hello';
} else {
this.$router.replace('/hello') // this work perfectly
console.log(window.location.host + "/hello" ); // this is returning the intended address: localhost:8080/hello
}
} else {
toastr.warning("Oops something went wrong on login!");
}
}).catch(error => {
// dealing with redirection result errors from Google Authentication
});
This is my index.js routing file (I am doing some route guarding here so it may be useful for you to get a bigger picture if I paste the file):
import Vue from 'vue'
import Router from 'vue-router'
import firebase from '../firebase-config'
import {store} from '#/store/store'
import hello from '#/components/hello'
import login from '#/components/login'
import landing from '#/components/landing'
Vue.use(Router)
let router = new Router({
mode: 'history',
routes: [
{
path: '*',
redirect: '/landing'
},
{
path: '/',
redirect: '/landing'
},
{
path: '/landing',
name: 'landing',
component: landing
},
{
path: '/login',
name: 'login',
component: login
},
{
path: '/hello',
name: 'hello',
component: hello,
meta: {
requiresAuth: true
}
},
],
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
firebase.auth().onAuthStateChanged(function(user) {
if (!user) {
next({
path: '/landing'
})
} else {
next()
}
});
} else {
next()
}
})
export default router
Any thoughts?
I have used cordova- 2.5.0 & facebook-sdk 3.0.2 in fb plugin.It works fine when device does not have native app installed. when native app is installed nothing is happened.means it cant get current access token of user.Any idea? According to me there are two ways:
1) disable to get access native app just like in ios. But its not right way as if user is allready login in native then he has to login again in my plugin setup.
2)dont know how to solve this issue.There is no issue with hash key as it is right and works well in ios using my first way.
So my question is that how to prevent to accessing native app? OR Is there any other way to solve this issue?
As i dont get anything. when i am going to get user's friend list it shows An active access token must be used to query information about the current user.,"type":"OAuthException","code":2500.
cdv-pluggin-fb-connect.js
CDV = ( typeof CDV == 'undefined' ? {} : CDV );
var cordova = window.cordova || window.Cordova;
CDV.FB = {
init: function(apiKey, fail) {
// create the fb-root element if it doesn't exist
if (!document.getElementById('fb-root')) {
var elem = document.createElement('div');
elem.id = 'fb-root';
document.body.appendChild(elem);
}
cordova.exec(function() {
var authResponse = JSON.parse(localStorage.getItem('cdv_fb_session') || '{"expiresIn":0}');
if (authResponse && authResponse.expirationTime) {
var nowTime = (new Date()).getTime();
if (authResponse.expirationTime > nowTime) {
// Update expires in information
updatedExpiresIn = Math.floor((authResponse.expirationTime - nowTime) / 1000);
authResponse.expiresIn = updatedExpiresIn;
localStorage.setItem('cdv_fb_session', JSON.stringify(authResponse));
FB.Auth.setAuthResponse(authResponse, 'connected');
}
}
console.log('Cordova Facebook Connect plugin initialized successfully.');
}, (fail?fail:null), 'org.apache.cordova.facebook.Connect', 'init', [apiKey]);
},
login: function(params, cb, fail) {
params = params || { scope: '' };
cordova.exec(function(e) { // login
if (e.authResponse && e.authResponse.expiresIn) {
var expirationTime = e.authResponse.expiresIn === 0
? 0
: (new Date()).getTime() + e.authResponse.expiresIn * 1000;
e.authResponse.expirationTime = expirationTime;
}
localStorage.setItem('cdv_fb_session', JSON.stringify(e.authResponse));
FB.Auth.setAuthResponse(e.authResponse, 'connected');
if (cb) cb(e);
}, (fail?fail:null), 'org.apache.cordova.facebook.Connect', 'login', params.scope.split(',') );
},
logout: function(cb, fail) {
cordova.exec(function(e) {
localStorage.removeItem('cdv_fb_session');
FB.Auth.setAuthResponse(null, 'notConnected');
if (cb) cb(e);
}, (fail?fail:null), 'org.apache.cordova.facebook.Connect', 'logout', []);
},
getLoginStatus: function(cb, fail) {
cordova.exec(function(e) {
if (cb) cb(e);
}, (fail?fail:null), 'org.apache.cordova.facebook.Connect', 'getLoginStatus', []);
},
dialog: function(params, cb, fail) {
cordova.exec(function(e) { // login
if (cb) cb(e);
}, (fail?fail:null), 'org.apache.cordova.facebook.Connect', 'showDialog', [params] );
}
};
Thanks in Advance!!
I was able to get it working with this plugin: https://github.com/jimzim/phonegap-facebook-android-sample