var pushnotifications = require('com.arellomobile.push');
Ti.API.info("module is => " + pushnotifications);
pushnotifications.pushNotificationsRegister("595043289423", "60666-9265D", {
//NOTE: all the functions fire on the background thread, do not use any UI or Alerts here
success:function(e)
{
Ti.API.info('TITAIUM!!! JS registration success event: ' + e.registrationId);
alert('TITAIUM!!! JS registration success event: ' + e.registrationId);
},
error:function(e)
{
Ti.API.error("TITAIUM!!! Error during registration: "+e.error);
alert("TITAIUM!!! Error during registration: "+e.error);
},
callback:function(e) // called when a push notification is received
{
alert("in callback");
Ti.API.info('TITAIUM!!! JS message event: ' + JSON.stringify(e.data));
//alert('notification data is=' +JSON.stringify("notification data="+e.data));
}
});
Related
I'm using snapshot listener for the first time and I can't figure out why it only updates only the window that changes the database.
I'm trying to make a chat system that updates for the sender window and the reciever window when the message is sent but it only updates the sender window.
Here is the function that sends the message and listens for snapshots:
function sendMessage() {
// Activate the chat for the reciever
setDoc(
doc(database, `users/${activeChatEmail}/activeChats/${userUsername}`),
{
ProfileUsername: userUsername,
ProfileIcon: userIcon,
ProfileEmail: userEmail,
LastMessageId: lastActiveChatMessageId + 1,
}
);
// Insert the message into chatter database **
setDoc(
doc(
database,
`users/${userEmail}/activeChats/${activeChatUsername.value}/chats/${
lastActiveChatMessageId + 1
}`
),
{
message: message.value,
sender: userUsername,
}
);
// Insert the message into reviercer database
setDoc(
doc(
database,
`users/${activeChatEmail}/activeChats/${userUsername}/chats/${
lastActiveChatMessageId + 1
}`
),
{
message: message.value,
sender: userUsername,
}
);
// Update last message id
updateDoc(
doc(database, `users/${userEmail}/activeChats/${activeChatUsername.value}`),
{
LastMessageId: lastActiveChatMessageId + 1,
}
).then(() => {
lastActiveChatMessageId += 1;
});
onSnapshot(
doc(database, `users/${userEmail}/activeChats/`, activeChatUsername.value),
(docInfo) => {
messages.value.push({
message: message.value,
name: userUsername,
});
message.value = "";
}
);
}
I am trying to implement GTM and new Google analytics web + app and I can see its taking 5sec to push data to google analytics.
I have tested with a fresh site and simple tracking event on click in link.
https://drive.google.com/file/d/1ILJLROq05OQwx3oXXCrOVXDeoxtbdKVw/view?usp=sharing
document.addEventListener('click', function (event) {
// If the clicked element doesn't have the right selector, bail
if (!event.target.matches('.btn-GA')) return;
// Don't follow the link
event.preventDefault();
// Log the clicked element in the console
console.log('Click......');
dataLayer.push({
"event": "wa_trigger",
"wa_event": "bounce_out",
"wa_action": "bounce_action",
"wa_label": "bounce_label"
});
}, false);
<a class="btn-GA" href="#">TEST CLICK</a>
================================================
UPDATE::::
Thanks for your answer. I noticed its really fast if I set true for the GA debug https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna and the hit comes fast and first others hit.. but when its off the hit comes at then end after 5sec.
And here screenshot from console:
https://drive.google.com/file/d/1a4n1WldESjbwTYkwiQ9PPX9RijigDApt/view?usp=sharing
Here the push and hit
Here push =====>
a.js:6 Google - dataLayer.push(): event: wa_trigger
a.js:6 ~ Object:
{
event: "wa_trigger",
wa_event: "logo-click"
}
Currently in memory: {event: "wa_trigger", wa_event: "logo-click", eventCallback: ƒ}
a.js:6 ~ Call Stack
a.js:6 ~ 20.140 s since Document Start
And here the hit: ====>
~ Data: {
events: [
{
en: "-logo-click",
_et: "2258",
ep.transport: "beacon"
},
{
en: "page_view",
_et: "36",
ep.transport: "beacon"
}
],
v: "2",
tid: "G-xxxxxx",
gtm: "xxxx",
_p: "109194814",
sr: "1440x900",
ul: "sv-se",
cid: "2129079382.1587074095",
dl: "http://www.site.lo/",
dr: "",
dt: "Site title",
sid: "1587312754",
sct: "5",
seg: "1",
_s: "2",
statusCode: 204
}
~ Network Hit: {frameId: 0, fromCache: false, initiator: "http://www.site.lo", ip: "216.58.207.206", method: "POST", …}
dlc.js:1208 ~ 26.208s since Document Start
dlc.js:1208 ~ 4.316s since last hit
It looks to be "by design":
One thing you might have noticed is the delay it takes for the hit to
be sent. When you load the page, you can see how the browser waits a
few seconds before dispatching the hit to GA. This is because GAv2
batches requests automatically, which, again, is a great feature
upgrade.
One thing you might have noticed is the delay it takes for the hit to
be sent. When you load the page, you can see how the browser waits a
few seconds before dispatching the hit to GA. This is because GAv2
batches requests automatically, which, again, is a great feature
upgrade.
By batching multiple hits into a single request, browser resources are
saved for other things. The delay is due to the browser waiting to see
if other hits should be dispatched together with the Page View.
https://www.simoahava.com/analytics/getting-started-with-google-analytics-app-web/
Be confident that the hit will fire before the user leaves the page !
Ok, I did my best to fix the issue and I used fetch to send the data directly to google server and skip the dataLayer and by using Callback function and a bit delay 1sec to wait for GA to be loaded.
Here how I did it and I am not sure if this is the best way or not but its working 100% and I got exact data on both old and old data.
BounceOut is the old data GA1
Bounce_out and Bounce_out_source is the new one GA2
trackAndBounceOut(url, callback) {
var action = this.state.bouncer.meta.partnerName
var label = this.state.bouncerId
var type = Session.page
window.dataLayer = window.dataLayer || []
var checkGA
setTimeout(function () {
if (ga && typeof ga.getAll == 'function') {
checkGA = true
} else {
checkGA = false
}
if (checkGA) {
var clientId = ga.getAll()[0].get('clientId');
var adSenseId = ga.getAll()[0].get('adSenseId')
var screenResolution = ga.getAll()[0].get('screenResolution')
var userLanguage = ga.getAll()[0].get('language')
var docReferrer = ga.getAll()[0].get('referrer')
var docLocation = ga.getAll()[0].get('location')
var debug = false // Enable for debug!!
var doctTitle = document.title
var stringUrlData = {
v: 2,
tid: 'G-XXXXXXXXXX',
gtm: 'XXXXXX',
_p: adSenseId,
sr: screenResolution,
ul: userLanguage,
cid: clientId,
dl: docLocation,
dr: docReferrer,
dt: doctTitle,
_dbg: debug ? 1 : '',
}
var urlString = Object.keys(stringUrlData)
.filter(analyticsKey => stringUrlData[analyticsKey])
.map(analyticsKey => analyticsKey + '=' + encodeURIComponent(stringUrlData[analyticsKey]))
.join('&')
var bounce_out = 'en=Bounce_Out&ep.Action=' + action
var bounce_out_source = 'en=Bounce_Out_source&ep.Action=' + type + '_' + action + '&ep.Label=' + type
fetch('https://www.google-analytics.com/g/collect?' + urlString + '&' + bounce_out, { method: 'POST' })
fetch('https://www.google-analytics.com/g/collect?' + urlString + '&' + bounce_out_source, { method: 'POST' })
if (Session.page == 'Partner') {
window.dataLayer.push(
{ 'event': 'pageEvent', 'Category': 'Partner page', 'action': 'Bounce Out', 'label': Session.page + '_' + action },
)
var partner_bounce_out = 'en=Partner_bounce-out&ep.Action=' + action
fetch('https://www.google-analytics.com/g/collect?' + urlString + '&' + partner_bounce_out, { method: 'POST' })
}
}
callback(action, type, label, url)
}.bind(this), 1000);
}
trackAndBounceOutRedirect(action, type, label, url) {
window.dataLayer.push(
{
'event': 'bounceOut',
'action': action,
'label': type + '_' + label,
'eventCallback': () => {
window.location.href = url
},
'eventTimeout': 1000
}
)
}
// And here then we call the main function and send the callback one:
this.trackAndBounceOut(this.state.bouncer.url, this.trackAndBounceOutRedirect)
I am building audio calling app and I am struggling to send data between the call receiver to the caller. Here is my code (In the call receiver):
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
peer.on('call', function(call) {
console.log("call.peer: " + call.peer)
conn = peer.connect(call.peer)
bootbox.dialog({
className: "modal-danger nonumpad",
closeButton: false,
animate: true,
title: 'Call Recieved',
message: "Accept or Decline",
onEscape: null,
buttons: {
pickup: {
label: "<i class=\"fa fa-phone\"></i> Answer",
className: "btn-warning btn-lg pull-left",
callback: function(){
conn.send('ACCEPT') // send Accept to the caller
return false
}
},
hangup: {
label: "<i class=\"fa fa-phone\"></i> Decline",
className: "btn-warning btn-lg pull-left",
callback: function(){
conn.send('DECLINED') // Send Decline to the caller
return false;
}
}
}
});
});
With the above code, when I make the call, dialog appears and when I press one of the options, data should be sent to the caller.
Here is the caller code, who receives the above sent data:
peer.on('open', function () {
Meteor.users.update(Meteor.userId(), { $set: { 'profile.peerId': peer.id } })
console.log(Meteor.user().profile.peerId);
peer.on('connection', function(conn) {
conn.on('data', function(data){
console.log(data);
});
});
});
Nothing is printed to the console.
What am I doing wrong here?
The connection event isn't important. You want to listen to the call event like this
peer.on('call', function (incomingCall) {
Hopefully that will work better for you.
I wouldn't update the user record with the peerId, Meteor don't recommend using it, as the authentication system also writes to it. I have used dburles:presence successfully, and in fact passed the presence id to peerjs to use (rather than letting peerjs allocate one)
Polymer 1.* and Firebase
How can do a async operation where this.$$('#ironAjax').generateRequest(); is call after return '{"Authorization": "Bearer ' + token + '"}';? I have to return the header value and then invoke the iron-ajax request.
<iron-ajax
url="[[HOST]][[LISTINGS]]?foo=foo"
id="ironAjax"
handle-as="json"
headers="[[setAuth()]]",
on-error="errorHandler"
loading="{{ironLoading}}"
last-response="{{listings}}"></iron-ajax>
pageActivated: function(activated) {
if (activated) {
this.setAuth();
}
},
setAuth: ()=> {
firebase.auth()
.onAuthStateChanged((token) => {
return '{"Authorization": "Bearer ' + token + '"}';
this.$$('#ironAjax').generateRequest(); // NEED TO CALL AFTER
// HEADER IS SET
})
I was able to handle the situation with a direct modification to the header. Hopefully this can help anyone else in the same situation:
Behavior:
<script>
AuthIronAjax = {
rawSetAuth: (user, ajax) => {
if (user) {
user.getIdToken().then((token) => {
ajax.headers['Authorization'] = 'Bearer ' + token;
ajax.generateRequest();
});
}
},
setAuth: function (ajax) {
firebase.auth()
.onAuthStateChanged((user)=> this.rawSetAuth(user, ajax));
}
};
</script>
Element it is used in. Note: iron-pages is being used with a implied host property binding activated:
observers: ['pageActivated(activated)'],
behaviors: [AuthIronAjax],
pageActivated: function(activated) {
if (activated) {
this.setAuth(this.$.ironAjax);
}
},
I currently have a Page Fragment with the following code that creates an entry for a datasource and sends out an email (code below) notifying everyone.
Button:
newSalesEmailMessage(widget);
widget.datasource.createItem();
app.closeDialog();
Client Script Email notification code:
/**
* Calls a server method to send an email.
* #param {Widget} sendButton - widget that triggered the action.
*/
function newSalesEmailMessage(sendButton) {
var pageWidgets = sendButton.root.descendants;
var fullName = app.datasources.Directory.item.FullName;
var htmlbody = '<b><font size="3">' + fullName + '</font></b>' + ' has created a new sales entry for: ' +
'<h1><span style="color:#2196F3">' +pageWidgets.ProjectName.value + '</h1>' +
'<p>Contact: <b>' + pageWidgets.Contact.value + '</b>' +
'<p>Sales Person: <b>' + pageWidgets.SalesPerson.value + '</b>' +
'<p>Notes: <b>' + pageWidgets.Notes.value + '</b>';
google.script.run
.withSuccessHandler(function() {
})
.withFailureHandler(function(err) {
console.error(JSON.stringify(err));
})
.sendEmailCreate(
'test#email.com',
'New Sales Entry for: ' + pageWidgets.ProjectName.value,
htmlbody);
}
onCreate code for the Model:
// onCreate
var email = Session.getActiveUser().getEmail();
var directoryQuery = app.models.Directory.newQuery();
directoryQuery.filters.PrimaryEmail._equals = email;
var reporter = directoryQuery.run()[0];
record.reported_by = email;
record.reported_full_name = reporter.FullName;
record.Date = new Date();
Everything works except for the fullName option. It keeps pulling my name even when another user creates an entry (maybe because I am an admin?). I have a Directory Model setup and that seems to work for when I am displaying the full name for a users's comments.
I would like to have fullName = the name of the person currently creating the entry.
Thank you for your help!
App Startup Script:
// App startup script
// CurrentUser - assuming that it is Directory model's datasource
// configured to load record for current user.
loader.suspendLoad();
app.datasources.Directory.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
You need to filter your Directory model datasource. If you are planning to use it for different purposes, then I'll recommend to create dedicated datasource for current user. You can filter it on server (preferable) or client side:
Filter on server, load on client:
// Directory model's Server Script for Current User datasource
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
return query.run();
// ------------------------
// Your startup script will remain almost the same:
loader.suspendLoad();
app.datasources.CurrentUser.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Client-only:
var currentUserDs = app.datasources.CurrentUser;
currentUserDs.query.filters.PrimaryEmail._equals = app.user.email;
loader.suspendLoad();
currentUserDs.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Thank you to Pavel. Everything worked, but it took me a few to understand exactly what I needed to do. For those who want to try and replicate what I did here were the steps.
First I had to create a Directory Model.
Then under the App Settings section for the app itself (click the gear) I put the following code under the App Startup Script - Client Script section:
loader.suspendLoad();
app.datasources.CurrentUser.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Next I went under the Datasources section for the Directory model and added a datasource called CurrentUser.
In the Query - Server Script section I put:
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
return query.run();
This filters the datasource so that the only entry in there is the current user. Then I adjusted my "var fullName" in the email Client Script to point to the new datasource:
/**
* Calls a server method to send an email.
* #param {Widget} sendButton - widget that triggered the action.
*/
function newSalesEmailMessage(sendButton) {
var pageWidgets = sendButton.root.descendants;
var fullName = app.datasources.CurrentUser.item.FullName;
var htmlbody = '<b><font size="3">' + fullName + '</font></b>' + ' has created a new sales entry for: ' +
'<h1><span style="color:#2196F3">' +pageWidgets.ProjectName.value + '</h1>' +
'<p>Contact: <b>' + pageWidgets.Contact.value + '</b>' +
'<p>Sales Person: <b>' + pageWidgets.SalesPerson.value + '</b>' +
'<p>Notes: <b>' + pageWidgets.Notes.value + '</b>';
google.script.run
.withSuccessHandler(function() {
})
.withFailureHandler(function(err) {
console.error(JSON.stringify(err));
})
.sendEmailCreate(
'test#email.com',
'New Sales Entry for: ' + pageWidgets.ProjectName.value,
htmlbody);
}