How to create a share link in Buildfire - buildfire

I'm attempting to create a share link that users within a plugin can send to friends via email or sms. If their friend has the app, the goal would be to open the app to the plugin with a query string similar to navigation.navigateTo does so that it would open to specific content within the plugin. If they don't, the goal would be to send them to the app's webpage where they could download the app from the appropriate store (android or apple). Is this possible or at least a portion of it?
I've generated a share link using buildfire.deeplink.generateUrl but can't find the appropriate steps from there in the API documentation.

Yes, The steps as following:
generate the deeplink URL
buildfire.deeplink.generateUrl(options, callback)
make sure of passing data property to options where its representing the
deep link data that developers need to provide to the plugin once the user
opened the share link. For more information on how to reed this data from
plugin, see buildfrire.deeplink.getData.
buildfire.deeplink.generateUrl(
{
data: { videoId: "9Q-4sZF0_CE" },
},
(err, result) => {
if (err) {
console.error(err);
} else {
console.log(result.url);
}
}
);
after generate the deep link use the following function to open share device options
buildfire.device.share({ link: deepLinkUrl }, callback);
Finally you have to handle deeplink data in you plugin to be able to open desired content based deeplink data that you pass during generate the deeplink URL, check this buildfrire.deeplink.getData.
For more details check the doc.
Example
// share function
const share = () => {
let deeplinOptions= {};
deeplinOptions.title = 'Hello world';
deeplinOptions.type = "website";
deeplinOptions.description = 'First program';
deeplinOptions.imageUrl = '<IMAGE URL>';
deeplinOptions.data = {
"link": vidId
};
buildfire.deeplink.generateUrl(deeplinOptions, function (err, result) {
if (err) {
console.error(err);
} else {
let options = {
link: result.url
};
let callback = function (err, result) {
if (err) {
console.warn(err);
};
};
buildfire.device.share(options, callback);
};
});
};
// Handle Deeplink data in your plugin
const handleDeepLinkData = () => {
buildfire.deeplink.getData(function (data) {
if (data && data.link) {
let vidId= data.link;
// Do what you want
}
// Do what you want
});
}

Yeah, Just share the result URL

Related

No match when searching a (Docker) Server using ldapjs

I have an Ldap Server running on Docker + ldapjs. This server is adding a set of records that I am trying to search for with the client.
A sample user object looks like below:
{
user: 'cn=first.last,ou=user_group,o=main',
info: {
cn: 'first.last',
email: 'first.last#mail.com'
}
}
The options would look like this:
let opts = {
scope: 'base',
attributes: ['dn', 'sn', 'cn', 'user', 'info']
};
I'm using this code in a class, so I bind in the constructor, after initializing the client:
constructor(url) {
client = ldap.createClient({
url: url
});
client.on('error', (err) => {
log.error(`${err}`);
});
client.bind(username, password, function (err) {
if (err) {
log.error(`${err}`);
}
});
log.info('Client Initialized.');
};
And my search code:
return new Promise((resolve, reject) => {
var record = {};
client.search(username, opts, function (err, res) {
res.on('searchEntry', function (entry) {
log.info(`Record Retrieved: ${JSON.stringify(entry.object)}`);
record = entry.object;
});
res.on('error', function (err) {
log.error(`Error: ${err.message}`);
});
res.on('end', function (result) {
if (err) {
reject(err);
}
else {
log.info(`Status: ${result.status}`);
resolve(record);
}
});
});
});
The issue I'm experiencing is that the code will always resolve on end when I make a search request from the client, which means that I never get a match, although it's definitely there.
I've tried:
Binding inside and outside the promise instead. No difference.
Changing the user structure and username used in client.search. No difference.
Searching for only 'cn=first'. I do get an error that it doesn't exist, which is good.
Adding a filter in options and changing the parameters there, but still no result.
I connect to the server ok, bind is ok as well, so I think I'm either doing the search wrong, or the way I have structured the users in the server is not proper.
Added screenshot showing server logs: The user added in the entry looks like it has a different name, but I changed it to match in the data.
I've found the issue, which was related to the structure I was using in my records, I've solved it using an ldapts client instead, but the same logic can be used in an ldapjs client:
Specifically:
This is a record in my ldapjs Server:
{
name: 'John Doe',
uid: 'john.doe',
dn: 'uid=john.doe, ou=users, o=server',
email: 'john.doe#email.com',
userprincipalname: 'cgi-doej',
}
This is how I search for it:
let attributes = ['cn'], filter = `(email=${email})`
const { searchEntries, searchReferences } = await this.client.search(searchDN, {
scope: 'base',
filter: filter,
attributes: attributes
});
This has solved my issues.

Automation Testing - Checking of PDF content using WebdriverIO

I am currently working on with a test automation that focuses on verifying the data on a PDF file if it matches the data on my webpage and API using WebdriverIO with NodeJS.
I’m browsing for some resources but can’t seem to find a solution that suitable for the tool I’m using. I hope someone could help me. Thank you
You can use npm packages pdf-parse or pdfreader.
For example:
// const { PdfReader } = require("pdfreader");
const pdf = require('pdf-parse');
module.exports = function data(filePath) {
return new Promise((resolve) => {
pdf(filePath).then(function(data) {
resolve(data.text)
})
})
}
// module.exports = function data (pathToPdf) {
// return new Promise((resolve) => {
// new PdfReader().parseFileItems(pathToPdf, (err, item) => {
// if (err) console.error("error:", err);
// else if (!item) console.warn("end of file");
// else if (item.text) resolve(item.text);
// })
// });
// }

Wait for firebase storage database pull to finish before rendering template in nodejs with async-await

I am trying to pull some images that are stored in firebase storage, create publicly accessible url's, then add them to an array which will be passed in as I render my template. However, each time my template renders first before the data is pulled and thus the array is empty. I basically need to find a way to render the template only when all the database pull is finished and I don't know how.I have dipped into async-await as a means to try to fix this problem but I have had no luck.
Here is my code:
async function readFiles () {
const [files] = await bucket.getFiles({ prefix: 'Resources/'});
files.forEach(file => {
//we have to get a signed public url in order to access the files stored in the cloud
file.getSignedUrl(signConfig, function(err, url) {
if (err) {
console.error(err);
return;
}
// The file is now available to read from this URL.
request(url, function(err, resp) {
resources.push(url) //append all the publicly avaialbe url's to the resources array
resp.statusCode = 200;
console.log("done request")
});
});
});
console.log("DONE READ FILES");
};
async function returnIndex() {
await readFiles(); //wait until read files is finished
console.log("TCL: returnIndex -> resources", resources);
res.render('advertiser/index.html', {resources: resources});
};
returnIndex();
And then here is my output(5 things stored in my database), basically indicating that all the public url's are added to the array after my template is rendered:
DONE READ FILES
TCL: returnIndex -> resources []
done request
done request
done request
done request
done request
Found a solution. It was to set a timeout for 0 ms... not sure exactly why this works but I think it has to do with the difference in a microtask vs a macrotask on the event loop... Promises are microtasks and Settimeout is a macrotask, so the Settimeout will be executed last and thus the information from the database is pulled correctly
var resources = new Array();
const [files] = await bucket.getFiles({ prefix: 'Resources/'});
// Lists all resources in their bucket
function readFiles () {
files.forEach(file => {
file.getSignedUrl(signConfig, function(err, url) {
if (err) {
console.error(err);
return;
}
resources.push(url)
// The file is now available to read from this URL.
request(url, function(err, resp) {
resp.statusCode = 200;
});
});
});
setTimeout(function(){res.render('advertiser/index.html', {resources: resources})}, 0);
};
readFiles();

nativescript-audio plugin does not function on ios

I have succesfully implemented the nativescript-audio plugin on android. I am using plain JS in my project. When i run it on ios i get the following error.
NSURLErrorDomain Code= -1002 "unsupported url".
I get this error with most of the examples that i found on the web (including the following , which works perfectly on android).
var ns_audio = require("nativescript-audio");
var player = new ns_audio.TNSPlayer();
var playerOptions = {
audioFile: "http://www.noiseaddicts.com/samples_1w72b820/2514.mp3",
loop: false,
completeCallback: function () {
console.log('completePlayer')
},
errorCallback: function (errorObject) {
console.log(JSON.stringify(errorObject));
},
infoCallback: function (args) {
console.log(JSON.stringify(args));
}
};
player.playFromUrl(playerOptions)
.then(function (res) {
console.log(res);
})
.catch(function () {
console.log("didn't work...");
})
It looks like recording works (no errors, and the correct responses, although i cannot test if the file has been correctly created...) But playback gives this error. Any idea ?
I have created a plain JS playground for you. I have tested the mp3 URL that you have provided in the the post and that works fine on ios.
Have a play with that and see if you are missing something. Here is
function pageLoaded(args) {
var page = args.object;
const player = new audio.TNSPlayer();
const playerOptions = {
audioFile: 'http://www.noiseaddicts.com/samples_1w72b820/2514.mp3',
loop: false,
completeCallback: function () {
console.log('finished playing');
},
errorCallback: function (errorObject) {
console.log(JSON.stringify(errorObject));
},
infoCallback: function (args) {
console.log(JSON.stringify(args));
}
};
player
.playFromUrl(playerOptions)
.then(function (res) {
console.log(res);
})
.catch(function (err) {
console.log('something went wrong...', err);
});
page.bindingContext = homeViewModel;
}
Recording and Playback with the nativescript-audio plugin (for iOS) are both working now!. My first problem was that i needed to record to .caf (not .mp3) so i used
if(isAndroid)
{
extention = ".mp3";
}
else
{
extention = ".caf";
}
before i record the audio file....
Also i ran in a stupid oversight which is easy to miss....
i created my code from the above mentioned example, but because i play the sound that is recorded to a .caf file. i needed to use playFromFile and not playFromUrl as the example uses.
( thats what caused the error : NSURLErrorDomain Code= -1002 "unsupported url".)
player
.playFromFile(playerOptions)
.then(function (res) {
hopefully this point of attention can save someone a headache !

secure user email in Meteor

I have a list of users. I don't want to publish all user data to the client, especially emails. I have multiple publish methods where i can use:
Meteor.publish('usersData', function() {
return Users.find({}, {
fields: {
emails: 0
}
});
});
But what if I or other programmer forget to filter fields and just publish whole collection:
Meteor.publish('users', function() {
return Users.find();
});
It's a problem. There should be global settings to filter data in collection. Is there any way how to do it in current (0.6.6.3) Meteor?
You can create a method you use instead of the normal collection.find method that you use anywhere you need to publish users. An example could be:
function findUsers(query) {
return Meteor.users.find(query || {}, { fields: { emails: 0 } });
}
And then you can just remind your programmers to use the findUsers method:
Meteor.publish('userData', function () {
return findUsers({ points: { $gt: 5 } });
});
How about writing a collection observer that throws an exception whenever a user with email fields present was published.
The observer runs independently for each connected user and triggers every time a user object has been pushed to the user collection. If it is not the current user, throw an error if the object contains the email field.
Your team should then notice these exceptions during development.
Meteor.publish("userCheck", function () {
var self = this;
var handle = Meteor.users.find({}).observeChanges({
added: function(id) {
var user = Meteor.users.findOne({_id: id});
if (user.emails && self.userId !== id) {
throw new Meteor.Error(500, "Must not publish other people's email!");
}
}
});
self.ready();
self.onStop(function () {
handle.stop();
});
});

Resources