Cordova firefoxos web access issue - networking

I'm trying to port my properly working (in iOS, Android) cordova app to Firefoxos.
The simulator starts properly and its browser can load web pages BUT my app cannot load data from the web.
Looking at console I see the following errors:
"JavaScript error: app://aa2a2c24-a8d6-447d-92da-4f2e9af65661/plugins/org.apache.cordova.network-information/src/firefoxos/NetworkProxy.js, line 33: missing : after property id" simulator-process.js:44
"JavaScript error: app://aa2a2c24-a8d6-447d-92da-4f2e9af65661/cordova.js, line 1120: Module org.apache.cordova.network-information.NetworkProxy does not exist."
Any suggestion? Thanks.
Cordova 3.5.0
Simulator FirfeoxOS 1.3 and FirfeoxOS 1.4

After some research I figured out the issues
1- Despite upgrading cordova to 3.5.0 I must remember that plugins don't get automatically update.
To get the plugin code for firefoxos updated I added again the same plugin, removed the firefoxos platform and reinstalled it again.
At that point the javascript errors were gone
2- Then the ajax call were still not accessible due to permissions. To ensure you can have ajax call you have to put in your manifest.webapp the following code
"type": "privileged",
"permissions": {
"systemXHR": { "description": "Required for AJAX calls in app"}
}
Both "type" and "permissions" are needed
3- Finally you have to ensure the ajax calls use
mozSystem: true
Specifically for jquery, you could put something like the following on top of your js file:
if (device.platform == 'firefoxos') {
$.ajaxPrefilter( function( options ) {
if ( options.firefoxOS ) {
options.xhr = function() {
return new window.XMLHttpRequest( {
mozSystem: true
} );
}
}
} );
$.ajaxSetup( {
firefoxOS: true
} );
}
Now I can properly handle ajax calls.

Related

Authorization error when trying to apply an index template to elasticsearch

so we have an elastic search service running in AWS, the elasticsearch version is 7.8.0. And I need to add an index template to limit the amount of shards that are allocated to new indices when they are added.
I followed this example of how to add an index template and got this very simple template:
PUT _index_template/shard_limitation
{
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
}
When running this request from the inside Kibana's Dev Tools console I get the following error: {"Message":"Your request: '/_index_template/shard_limitation' is not allowed."}. As well as an Unauthorized - 401 icon. I'm running this command with the admin user.
I tested it locally (elastic search running on my machine) and it all works fine. Any idea why this might happen?
SOLUTION:
As was suggested by #Ajinkya, the correct way to do this is to not include the "_index" before the template api. The correct way to achieve what I was trying to do is to type the following:
PUT _template/shard_limitation
{
"index_patterns": ["some-pattern"],
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
'_index_template' operation might not be supported in AWS elasticsearch. You can check supported operations for your AWS ES version here
You can still use '_template' API to add index template
PUT _template/shard_limitation
{
"index_patterns": ["test*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
}

How do I use cordova firebase.dynamiclinks plugin in Ionic 4?

I want to use Cordova Firebase Dynamiclinks plugin : https://github.com/chemerisuk/cordova-plugin-firebase-dynamiclinks#installation in my Ionic 4 App.
There is an Ionic-native-plugin usage for this too : npm install #ionic-native/firebase-dynamic-links and usage :
import { FirebaseDynamicLinks } from '#ionic-native/firebase-dynamic-links/ngx';
constructor(private firebaseDynamicLinks: FirebaseDynamicLinks) { }
...
this.firebaseDynamicLinks.onDynamicLink()
.subscribe((res: any) => console.log(res), (error:any) => console.log(error));
Issue is : I want to use createDynamicLink(parameters) method available in Cordova Firebase Dynamiclinks plugin but Ionic-native-plugin says
Property 'createDynamicLink' does not exist on type 'FirebaseDynamicLinks'.
Therefore, I need to use Cordova Firebase Dynamiclinks directly and I tried doing using it like
import { cordova } from '#ionic-native/core';
...
cordova.plugins.firebase.dynamiclinks.createDynamicLink({
link: "https://google.com"
}).then(function(url) {
console.log("Dynamic link was created:", url);
});
But got error
Property 'plugins' does not exist on type '(pluginObj: any, methodName: string, config: CordovaOptions, args: IArguments | any[]) => any'.
Also tried removing import
cordova.plugins.firebase.dynamiclinks.createDynamicLink({
link: "https://google.com"
}).then(function(url) {
console.log("Dynamic link was created:", url);
});
And got this
Property 'firebase' does not exist on type 'CordovaPlugins'.
What is the correct usage of cordova plugins?
Update
Ionic-native-plugin now contains all the methods available in Cordova Firebase Dynamiclinks plugin.
I believe this is more fitting of a comment, but I don't quite have the reputation for it yet.
Currently, there is a PR open in the #ionic-team/ionic-native repo (here). This exposes the extra methods, but until then you can use the original repo here to get your desired effect. In order to install the repo you will have to follow the directions in the Developer guide here. Cheers!
I have developed an ionic 5 app that uses Firebase Dynamic Links and it works great but it took some effort. I watched videos to understand how Firebase Dynamic Links work but there is certainly much that is not shown.
To answer the original question you can always manually create a dynamic link which is what I do in our solution. We created a dynamic link that would help users onboard (register an account). Our dynamic link has custom onboardingId which originates from the backend process and the link is presented to the user via SMS text message.
This is in app.component.ts constructor
Here is some code that happens when the user clicks the dynamic link:
// Handle the logic here after opening the app (app is already installed) with the Dynamic link
this.firebaseDynamicLinks.onDynamicLink().subscribe((res: any) => {
console.log('app was opened with dynamic link');
console.log(res);
/* This only fires on subsequent calls and not on app start 20220208 STR
console.log(JSON.stringify(res)); //"{"deepLink":"https://localhost/onboard?onboardingId=8ed634b0-53b7-4a0f-b67e-12c06019982a","clickTimestamp":1643908387670,"minimumAppVersion":0}"
var dynamicLink = JSON.parse(JSON.stringify(res));
var deepLink = dynamicLink.deepLink;
console.log(deepLink);
if (deepLink.indexOf("onboard")>=0){
this.isOnboarding = true;
}
alert("deepLink ="+ deepLink);
*/
}, (error:any) => {
console.log(error)
});
I originally thought that Firebase handles all of the magic if the user doesn't have the app installed. I was wrong! You MUST also handle the code to pickup the dynamic link after the app is installed.
The code below will read the dynamic link from the clipboard and survives the app install process. Placed in app.component.ts ngOnInit().
this.platform.ready().then(() => {
this.firebaseDynamicLinks.getDynamicLink().then((data) => {
//added 20220208 STR try to help open the deep link if app is just installed
if (data != null) {
console.log(JSON.stringify(data));
//alert("initializeApp():"+JSON.stringify(data));
var dynamicLink = JSON.parse(JSON.stringify(data));
var deepLink = dynamicLink.deepLink;
console.log("initializeApp():"+deepLink);
if (deepLink != "") {
if (deepLink.indexOf("onboard")>=0){
this.isOnboarding = true;
this.deepLinkToOnboard(deepLink);
}
}
}
});}
So to handle dynamic links after you have the Firebase plugin installed, you must have two sections of code; one for handling if the app is already installed and another for handling the dynamic link if the app is not installed.

firebase dynamic link generated via API open appstore

I'm creating a dynamic link via API.
How can I specify to open the AppStore if the app is not installed?
here the body for my request:
{
"dynamicLinkInfo": {
"domainUriPrefix": "https://wi.page.link",
"link": "https://wiapp.com.au/faq?promocode=mypromo_code",
"iosInfo": {
"iosBundleId": "com.direce.sr",
"iosFallbackLink":"id1356389392",
"iosAppStoreId":"id1368389392",
},
"socialMetaTagInfo" :{
"socialImageLink":"https://vignette.wikia.nocookie.net/doraemon/images/b/b8/Doraemon_2005.PNG/revision/latest?cb=20151207094313&path-prefix=en",
"socialTitle":"my titu",
"socialDescription":"descripotio"
}
},
"suffix": {
"option":"UNGUESSABLE"
},
}
this works if I create the dynamic link via firebase console, where I can specify what to do if app not installed
Ok!
found the problem, is the
"iosAppStoreId":"id1368389392"
it is different value if creating from the dashboard or for API,
so the correct one when doing from, API should be without the "id"
"iosAppStoreId":"1368389392"
You can add a parameter called iosInfo, which has a property called iosAppStoreId (the app store id).
Check the documentation page here.

How to send external data to OnlyOffice plugin

I am developing onlyoffice plugin, which need to consume data (like reportid, session details that will be used to load data from server) from launching application.
structure of page come out like:
launching page (editor.aspx)
-- iframe 1 to load editor
-- -- ifram 2 to load plugin
Here i want to access data from editor.aspx into iframe 2 (javascript)
I tried using queryString like window.parent.location.search but it only can traverse till iframe 1, but not main aspx page. As i don't have control on what loads in iframe 1 it didn't work.
Also i tried with cookies and localStorage but none worked out.
Please guide..
launching page (editor.aspx) -- iframe 1 to load editor -- -- ifram 2
to load plugin. Here i want to access data from editor.aspx into iframe
2 (javascript)
There is no way to get direct access to the iframe with editor, the only way to work with it is using document server plugins
Actually there is a way... Having spent a LOT of time analysing what is going on... finally found a nice way to exchange configs between the TOP frame and PLUGIN frame with just a few lines of code leveraging the onlyoffice API - without any hacks :)
Editor Config object:
config: {
"width" : "100%",
"height" : "100%",
"type" : "desktop",
"documentType": "text",
"token" : "{{token}}",
"document" : {
"title" : "{{document.name}}",
"url" : "{{downloadUrl}}",
...
events: {
'onReady': <application ready callback>, // deprecated
...
'onInfo': function ( data ) {
if ( data && data.data && data.data.getConfig ) {
docEditor.serviceCommand ( 'getConfig', config.document );
}
}
}
}
var docEditor = new DocsAPI.DocEditor("placeholder", config);
onInfo event will receive the request from your plugin.
Need to check the event data has getConfig attribute.
If it does, send back the config to the plugin.
Within your plugin's index.html add an inline script tag with this content:
// config ref
var config;
// Get ready to receive the response from TOP
window.parent.Common.Gateway.on ( 'internalcommand', ( data ) => {
if ( data.command === 'getConfig' ) {
config = data.data;
}
} );
// Send custom config request to TOP
window.parent.Common.Gateway.sendInfo ( { getConfig: true } );
It subscribes to the internalcommand Gateway events which will be called by TOP, then kick in the communication process by calling the sendInfo command. Because the editor and your plugins (most likely) will be hosted on the same domain, you can access it via the window.parent ref.
This will download the config.document configuration object and store it in the plugins local config variable automatically - when you click on the plugin in the toolbar.

Where to put native code for push notifications with new Meteor Mobile platform

After reviewing the new Mobile features with latest 1.0 version of Meteor, I'm not seeing where I would modify the Cordova code to add custom capabilities. For instance, I want to implement push notifications for my application on both iOS and Android. In both cases I would need to write some native code so that I could get devices registered and accept push notification messages.
Currently, I'm using MeteorRider to accomplish this and it works great. I have 3 separate projects for Meteor, Android and iOS. In the latter 2, I put the native code there necessary to accomplish this. One thing is for certain, you have to update the bootstrap classes in Cordova to allow registrations to work.
In Meteor 1.0, how would I go about accomplishing this with the out-of-the-box mobile feature?
Here's the objective-C code for accepting push notification registration responses that is required in Cordova's AppDelegate:
- (void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog( #"Device token is: %#", deviceToken);
// Convert to string that can be stored in DB
NSString *regId = [[deviceToken description] stringByReplacingOccurrencesOfString:#"<" withString:#""];
regId = [regId stringByReplacingOccurrencesOfString:#">" withString:#""];
regId = [regId stringByReplacingOccurrencesOfString: #" " withString: #""];
[[ApplePushNotificationService sharedInstance] application:application uploadDeviceToken:regId];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
TL;DR : The cordova project is in the .meteor/local/cordova-build subfolder.
The default AppDelegate.m gets created in the .meteor/local/cordova-build/platforms/ios/***YOUR_APP_NAME***/Classes subfolder.
If you add a top-level folder called cordova-build-override to your meteor project, the directory tree that it contains will be added to the .meteor/local/cordova-build folder just before the build and compilation step.
So, put your custom AppDelegate.m in a new folder called cordova-build-override/platforms/ios/***YOUR_APP_NAME***/Classes .
mkdir -p cordova-build-override/platforms/ios/foo/Classes
cp .meteor/local/cordova-build/platforms/ios/foo/Classes/AppDelegate.m cordova-build-override/platforms/ios/foo/Classes
The Meteor-Cordova integration page on the GitHub Meteor wiki is the best place (so far) to find the details of cordova development with meteor.
You put your cordova-specific code in plain javascript. It's best not to modify the native code if at all possible; instead, see if you can write your own cordova plugin and use it from your meteor app. The cordova PushPlugin plugin might do what you're looking for, but if not, you can use it as a reference.
This example below will create a new iOS app that uses a non-meteor cordova plugin, from scratch.
NOTE: This is a bare minimum example. Look at the meteor cordova camera plugin for a full example. The code below is based on that plugin.
# create a meteor app foo
meteor create foo
cd foo
# add the iOS cordova platform
meteor add-platform ios
# create a new meteor package, foo-camera.
# NOTE: You need to substitute your own meteor.com developer ID here
meteor create --package your_meteor_developer_id:foo-camera
Now, edit the packages/your_meteor_developer_id:foo-camera/package.js file to add the following:
// Add the camera cordova plugin at version 0.3.3
Cordova.depends({
'org.apache.cordova.camera': '0.3.3'
});
EDIT 1: This causes the plugin to be downloaded to your cordova plugins folder.
You can refer to a git tarball instead of a version number e.g. :
Cordova.depends({
'com.phonegap.plugins.facebookconnect': 'https://github.com/Wizcorp/phonegap-facebook-plugin/tarball/0e61babb65bc1716b957b6294c7fdef3ce6ace79'
});
source: meteor cordova wiki
While we're at it, limit our code to run only on the client, and export our FooCamera object so it can be used in the rest of our meteor javascript:
Package.onUse(function(api) {
api.versionsFrom('1.0');
api.export('FooCamera');
api.addFiles('your_meteor_developer_id:foo-camera.js','client');
});
Edit 2:
If your cordova plugin needs special configuration, you can define this in your meteor app's
mobile configuration file. It will get copied into
your app's config.xml .
E.g.
// ===== mobile-config.js ======
// Set PhoneGap/Cordova preferences
App.setPreference('SOME_SPECIFIC_PLUGIN_KEY','SOME_SPECIFIC_PLUGIN_VAL');
Your app's config.xml will then eventually result in the following:
<preference name="SOME_SPECIFIC_PLUGIN_KEY" value="SOME_SPECIFIC_PLUGIN_VAL"/>
Next, edit the JavaScript file in your package ( packages/your_meteor_developer_id:foo-camera/your_meteor_developer_id:foo-camera.js ) to expose the cordova functionality in a meteor-like manner. Use the official meteor mobile package examples as a reference.
(the code below is stolen shamelessly from the meteor github repo ) :
FooCamera = {};
FooCamera.getPicture = function (options, callback) {
// if options are not passed
if (! callback) {
callback = options;
options = {};
}
var success = function (data) {
callback(null, "data:image/jpeg;base64," + data);
};
var failure = function (error) {
callback(new Meteor.Error("cordovaError", error));
};
// call the cordova plugin here, and pass the result to our callback.
navigator.camera.getPicture(success, failure,
_.extend(options, {
quality: options.quality || 49,
targetWidth: options.width || 640,
targetHeight: options.height || 480,
destinationType: Camera.DestinationType.DATA_URL
})
);
};
Now, add your new (local) package to your meteor app.
meteor add your_meteor_developer_id:foo-camera
Edit your application's main HTML and JS to use your new meteor package.
In your foo.html , replace the hello template with this:
<template name="hello">
<button>Take a Photo</button>
{{#if photo}}
<div>
<img src={{photo}} />
</div>
{{/if}}
</template>
In your foo.js , replace the button click event handler with this:
Template.hello.helpers({
photo: function () {
return Session.get("photo");
}
});
Template.hello.events({
'click button': function () {
var cameraOptions = {
width: 800,
height: 600
};
FooCamera.getPicture(cameraOptions, function (error, data) {
Session.set("photo", data);
});
}
});
Now, plug your device in, make sure it's on the same network as your computer, and start both the meteor server and the ios app.
meteor run ios-device
# If you want to just use the emulator, use the following instead.
# but of course the camera won't work on the emulator.
#meteor run ios
XCode will open. You may need to set up your certificates and provisioning profiles before running your app (from XCode).
In another terminal, tail the logs:
tail -f .meteor/local/cordova-build/platforms/ios/cordova/console.log
Finally, publish your excellent meteor cordova plugin so that everyone else can use it. Edit package.js as per the meteor docs. Then:
cd packages/your_meteor_developer_id\:foo-camera
meteor publish

Resources