Port Admob to mobile web - node.js

I am in the depths of creating a mobile web game that I will soon release. I am interested in monetizing this app. I want the game to feel like its a regular app and therefore wish to have admob ads (with deep links to the app store). I have heard that these also have substantially higher cpm that adsense mobile. My question is this: if I "port" admob using node.js will the clicks and views be recorded as server side, i.e. coming from one place, or mobile, i.e. from the user?
Here are some resources I am thinking of using:
https://media.admob.com/api/v1/docs/
https://github.com/floatinghotpot/cordova-plugin-admob
Any thoughts?

I am the author of the plugin you mentioned: https://github.com/floatinghotpot/cordova-plugin-admob
The basic version has been deprecated, and the pro version is recommended: https://github.com/floatinghotpot/cordova-admob-pro
Instead of porting AdMob to mobile web, you can consider use Cordova to pack your html5 game as a hybrid APP, then publish to Apple AppStore or Google Play Store.
Use the AdMob plugin to present Ad in your app, then Google will pay you.
Only a few javascript lines to present the Ad, and the AdMob SDK will take care of Ad presenting and user click.
See the example code:
function onLoad() {
if(( /(ipad|iphone|ipod|android|windows phone)/i.test(navigator.userAgent) )) {
document.addEventListener('deviceready', initApp, false);
} else {
initApp();
}
}
var admobid = {};
if( /(android)/i.test(navigator.userAgent) ) {
admobid = { // for Android
banner: 'ca-app-pub-6869992474017983/9375997553',
interstitial: 'ca-app-pub-6869992474017983/1657046752'
};
} else if(/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
admobid = { // for iOS
banner: 'ca-app-pub-6869992474017983/4806197152',
interstitial: 'ca-app-pub-6869992474017983/7563979554'
};
} else {
admobid = { // for Windows Phone
banner: 'ca-app-pub-6869992474017983/8878394753',
interstitial: 'ca-app-pub-6869992474017983/1355127956'
};
}
// it will display smart banner at top center, using the default options
if(AdMob) AdMob.createBanner( {
adId: admobid.banner,
position: AdMob.AD_POSITION.TOP_CENTER,
autoShow: true } );

Related

How to configure Azure App Service (for Mobile) and B2C Authentication and access Azure SQL Database

I have a xamarin.forms mobile App using Microsoft.WindowsAzure.MobileServices and Microsoft.Identity.Client. Using EasyAuth I successfully got the xamarin mobile app to post data to the AzureSQL tables linked via connection string in the App Service configuration section. I use the local and offline sync methods of MobileServiceClient. I then attempted to change to B2C authentication. I setup a Tenant and under this tenant registered a new App as a native client called "MobileB2C". Redirect URIs were added automatically. I then created the signinsignup UserFlows.
Back to the Azure App Service (Mobile) under Authentication section I added a provider and selected the B2C App, MobileB2C. I did not populate the "allowed token audiences" field and Azure automatically created Client secret setting name "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET" and the issuer URL.
So when I run the xamarin mobile app I can login via azure B2C and I can see that the authResult returns the users correct info along with UserIdentifier,aud, iss, sub, oid etc.
Once authResult is returned the xamarin mobile then tries to use the sync methods of MobileServiceClient to save data to the AzureSQL table. Its at this point that it fails. When the line await mClient.SyncContext.PushAsync().ConfigureAwait(false); is hit an error occurs described as Microsoft.WindowsAzure.MobileServices.Sync.MobileServicePushStatus.CancelledByAuthentication. I continued to try and confirgure the Azure back end differently and now I no linger get the CancelledByAuthentication error but instead get Microsoft.WindowsAzure.MobileServices.Sync.MobileServicePushStatus.CancelledByNetworkError.
The relevant xamarin mobile app code to implement the authentication and AzureSQL table update is as follows;
private B2CAuthenticationService()
{
// default redirectURI; each platform specific project will have to override it with its own
var builder = PublicClientApplicationBuilder.Create(B2CConstants.ClientID)
.WithB2CAuthority(B2CConstants.AuthoritySignInSignUp)
.WithIosKeychainSecurityGroup(B2CConstants.IOSKeyChainGroup)
.WithRedirectUri($"msal{B2CConstants.ClientID}://auth");
// Android implementation is based on https://github.com/jamesmontemagno/CurrentActivityPlugin
// iOS implementation would require to expose the current ViewControler - not currently implemented as it is not required
// UWP does not require this
var windowLocatorService = DependencyService.Get<IParentWindowLocatorService>();
if (windowLocatorService != null)
{
builder = builder.WithParentActivityOrWindow(() => windowLocatorService?.GetCurrentParentWindow());
}
_pca = builder.Build();
}
public async Task<UserContext> SignInAsync()
{
UserContext newContext;
try
{
// acquire token silent
newContext = await AcquireTokenSilent();
}
catch (MsalUiRequiredException)
{
// acquire token interactive
newContext = await SignInInteractively();
}
return newContext;
}
private async Task<UserContext> SignInInteractively()
{
AuthenticationResult authResult = await _pca.AcquireTokenInteractive(B2CConstants.Scopes)
.ExecuteAsync();
var newContext = UpdateUserInfo(authResult);
UserSingleton.Instance.UserId = newContext.UserIdentifier;
return newContext;
}
THe xamarin mobile app adds a record to the local database and then RefreshItemsAsync begins the synchronisation to the AzureSQL.
await azureService.AddUserSurveyAsync(newSurvey).ConfigureAwait(false);
await azureService.RefreshItemsAsync(true).ConfigureAwait(false);
It is at the PushAsync line below that the the code fails.
public async Task InitializeAsync()
{
using (await initializationLock.LockAsync())
{
if (!isInitialized)
{
mClient = new MobileServiceClient(https://mobileservice.azurewebsites.net);
// Define the offline store.
mStore = new MobileServiceSQLiteStore("mobile3.db");
mStore.DefineTable<UserSurvey>();
await mClient.SyncContext.InitializeAsync(mStore, new MobileServiceSyncHandler()).ConfigureAwait(false);
UserSurveyTable = mClient.GetSyncTable<UserSurvey>();
isInitialized = true;
}
}
}
public async Task RefreshItemsAsync(bool syncItems)
{
if (syncItems)
{
await SynchronizeAsync().ConfigureAwait(false);
}
}
public async Task SynchronizeAsync()
{
await InitializeAsync().ConfigureAwait(false);
IReadOnlyCollection<MobileServiceTableOperationError> syncErrors = null;
if (!CrossConnectivity.Current.IsConnected)
return;
try
{
await mClient.SyncContext.PushAsync().ConfigureAwait(false);
await UserSurveyTable.PullAsync("usersurveys", UserSurveyTable.CreateQuery()).ConfigureAwait(false);
}
catch (MobileServicePushFailedException error)
{
if (error.PushResult != null)
{
foreach (var result in error.PushResult.Errors)
{
await ResolveError(result);
}
}
}
}
What is wrong with the Azure back end configuration or perhaps I'm missing code as I can't understand how the xamarin mobile app can then attempt to communicate with the Azure Mobile App Service and AzureSQL as I don't send any token with those lines of code for PushAsync etc or perhaps this is abstracted away?
Here are images of the exceptions;
enter image description here
enter image description here
As promised, here is the succinct version of AAD authentication. For your purposes, B2C authentication is the same as AAD authentication.
There are two application definitions at play here - one for the mobile application (which basically says "this person is authenticated"), and one for the service (which says "a token authenticated for this mobile application can access this service"). So, you create an application ID for your mobile application, and an application ID for your service, and then you configure the service application ID to accept the mobile application.
The "WPF" tutorial for Azure Mobile Apps gives the general overview, although it's for WPF instead of Xamarin. The pieces you need are all the same.
The "WPF" tutorial here: https://learn.microsoft.com/en-us/azure/developer/mobile-apps/azure-mobile-apps/quickstarts/wpf/authentication

Trying to acquire Tizen TV Web App permission

I'm trying to build a POC Voice recognition app on the Tizen TV platform, but using Web application API I've failed at getting the permission for voice control.
Debug console prints: Cannot read property 'requestPermission' of undefined (in my case the global tizen object has no ppm property which in all examples on the Web should hold the requestPermission method).
function requestPermit(uri) {
return new Promise(function(resolve, reject) {
tizen.ppm.requestPermission(uri,
function(success) { resolve(success); },
function(error) { reject(error); });
});
}
var start = function() {
return requestPermit('http://tizen.org/privilege/voicecontrol.tts')
.then(function() { return init(); })
.catch(function(err) { return console.log(err); });
}
$(document).bind( 'pageinit', start );
As far as I know, the Privacy Privilege module of Web API is not supported on TV profile. There is no module Privacy Privilege on TV's docs here, so the behaviour you met is what I would expect - tizen.ppm is undefined.
Also basing on information here:
Since Tizen 4.0, the status of privacy-related privileges can be resolved at runtime using the Privacy Privilege API (in mobile and wearable applications).
There is no need to request a privilege on TV profile.
If you want to check in your code automatically, if the Privacy Privilege module is supported try:
if (tizen.systeminfo.getCapability("http://tizen.org/feature/security.privacy_privilege")) {
// ppm module is supported - you need to request privilege from the user here
} else {
// ppm module is not supported - just log or ignore, no consent from the user is needed
}

How to communicate between native and native web view running a flutter's web app?

Android allows specifying a Javascript interface to act as a bridge between the webview and Android code. Similarly, iOS provides the UiWebView stringByEvaluatingJavaScriptFromString method that allows communicating with the underlying webview.
But the issue is that once we build the flutter web app and say we include it as part of a web view in android , Then whenever communication needs to take place , there is some amount of code that we should write in both android side and javascript side manually.
Since editing javascript code generated from flutter web app build is impractical , we need a way to establish a communication channel on flutter side which will talk to the native side using the same type of javascript bridge above. This will be something similar to the method channels when using the flutter app on the native side directly.
So how would we inject or add our custom javascript code from inside flutter so that it will be added during compiling the js file ?
You can create a webmessage channel on the android side (iOS has an equivalent).
There is a description of how to do it here:
How Do You Use WebMessagePort As An Alternative to addJavascriptInterface()?
A brief setup on the javascript side looks like this - you would need to implement this in dart html:
const channel = new MessageChannel();
var nativeJsPortOne = channel.port1;
var nativeJsPortTwo = channel.port2;
window.addEventListener('message', function(event) {
if (event.data != 'capturePort') {
nativeJsPortOne.postMessage(event.data)
} else if (event.data == 'capturePort') {
/* The following three lines form Android class 'WebViewCallBackDemo' capture the port and assign it to nativeJsPortTwo
var destPort = arrayOf(nativeToJsPorts[1])
nativeToJsPorts[0].setWebMessageCallback(nativeToJs!!)
WebViewCompat.postWebMessage(webView, WebMessageCompat("capturePort", destPort), Uri.EMPTY) */
if (event.ports[0] != null) {
nativeJsPortTwo = event.ports[0]
}
}
}, false);
nativeJsPortOne.addEventListener('message', function(event) {
alert(event.data);
}, false);
nativeJsPortTwo.addEventListener('message', function(event) {
alert(event.data);
}, false);
nativeJsPortOne.start();
nativeJsPortTwo.start();
A similar solution for listening over using an eventlistener on the window in flutter web is below:
window.onMessage.listen((onData) {
print(onData.toString());
MessageEvent messageEvent = onData;
for (Property property in properties) {
if (messageEvent.data["id"] == property.id) {
});
} else if (messageEvent.data["northEastLng"] != null) {
print(messageEvent.data["northEastLat"]);
if (double.parse(messageEvent.data["northEastLat"]) == bounds.northEast.lat && double.parse(messageEvent.data["northEastLng"]) == bounds.northEast.lng){
return;
}
LatLng southWest = new LatLng(double.parse(messageEvent.data["southWestLat"]), double.parse(messageEvent.data["southWestLng"]));
LatLng northEast = new LatLng(double.parse(messageEvent.data["northEastLat"]), double.parse(messageEvent.data["northEastLng"]));
LatLngBounds incomingBounds = new LatLngBounds(southWest, northEast);
if (incomingBounds == bounds) {
return;
}
bounds = incomingBounds;
_propertyListPresenter.filterBounds(bounds);
}
}
});

Test Azure hosted WebApi locally to send Push Notifications to all devices

I apologize if my question is silly, but I am new to WebApi. I have followed a tutorial and published a WebApi to Azure. I also have created a Xamarin Mobile App and all the framework in Azure to be able to send Push Notifications to both Android and iOS. I have a notification hub set up, app service, web service that hosts the web api etc. Testing with Azure using the Push tab to send notifications individually to both ios and android works perfectly.
I posted the code of the web api. How can I use the web api locally on my computer to send a notification to both platforms (ios and android) please?
[RoutePrefix("sanotifications")]
public class SANotifController : ApiController
{
[HttpPost]
[Route("")]
public async Task<IHttpActionResult> SendNotificationAsync ([FromBody] string message)
{
//Get the settings for the server project
HttpConfiguration config = this.Configuration;
try
{
await InternalSendNotificationAsync(message, null);
}
catch (Exception ex)
{
//write the failure result to the logs
config.Services.GetTraceWriter().Error(ex.Message, null, "Push.SendAsync Error");
return BadRequest(ex.Message);
}
return Ok();
}
[HttpPost]
[Route("{installationid}")]
public async Task<IHttpActionResult> SendNotificationAsync(string installationId, [FromBody] string message)
{
//get the settings for the server project
HttpConfiguration config = this.Configuration;
try
{
await SendNotificationAsync(message, installationId);
}
catch (Exception ex)
{
//write the failure to the logs
config.Services.GetTraceWriter().Error(ex.Message, null, "Push.SendAsync Error");
return BadRequest(ex.Message);
}
return Ok();
}
async Task<NotificationOutcome> InternalSendNotificationAsync (string message, string installationId)
{
//Get the settings for the server project
HttpConfiguration config = this.Configuration;
//use code below if web api is already published to Azure to get existing setup
//does not work locally
var settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();
/*
//Get the Notification Hubs credentials for the Mobile App
string notificationHubName = settings.NotificationHubName;
string notificationHubConnection = settings.Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
*/
//the name of the Notification Hub from the overview page.
// works locally
string notificationHubName = "sa1hub";
//use "DefaultFullSharedAccessSignature" from the portal's Access Policies
string notificationHubConnection = "Endpoint=sb://sahub.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=71S2#QEWF##$";
// create a new notification hub client
var hub = NotificationHubClient.CreateClientFromConnectionString(
notificationHubConnection,
notificationHubName,
// Don't use this in RELEASE builds. The number of devices is limited.
// If TRUE, the send method will return the devices a message was
// delivered to.
enableTestSend: true);
// use a template compatible with both devices
// send the message so that all template registrations that contain "messageParam"
// will receive the notification. This includes APNS, GCM, WNS and MPNS template registrations.
var templateParams = new Dictionary<string, string>
{
["messageParam"] = message
};
// send the push notification and log the results
NotificationOutcome result = null;
if (string.IsNullOrWhiteSpace(installationId))
{
result = await hub.SendTemplateNotificationAsync(templateParams).ConfigureAwait(false);
}
else
{
result = await hub.SendTemplateNotificationAsync(templateParams, "$InstallationId:{" + installationId + "}").ConfigureAwait(false);
}
// Write the success result to the logs.
config.Services.GetTraceWriter().Info(result.State.ToString());
return result;
}
}
}
In Xamarin there are two way to send push notification from server to client. Even on Microsoft forum it's very clear step mention to Implementation.
Use of Azure Hub notification we can send easily notification on Cross mobile Platform or Native
Azure Push Notification
Another App Center Push notification Implementation.
Xamarin App Center Push Notification
To send push notification for IOS devices you have to communicate with APNS and for Android we need GCM. Azure works like an intermediate between our app and these services. So if you would like to send notification without Azure I prefer
Firebase Cloud Messaging. it is google product and allows us to send cross platform push notifications for both IOS and Android.
We can host our WebAPI in our windows local IIS and which should be configured for Firebase.
Example app for xamarin : FirebasePushNotificationPlugin

NFC Tag not working on Gear S2

Im trying to read the data in NFC tag using web development. I am able to detect tags from emulator, but on Gear S2 it does not work.
I have given all the privileges in config.xml
<tizen:privilege name="http://tizen.org/privilege/nfc.common"/>
<tizen:privilege name="http://tizen.org/privilege/nfc.tag"/>
<tizen:privilege name="http://tizen.org/privilege/bluetooth.admin"/>
<tizen:privilege name="http://tizen.org/privilege/nfc.admin"/>
<tizen:privilege name="http://tizen.org/privilege/nfc.cardemulation"/>
I am using whiztags NFC tags with Gear S2, they are working with my mobile(Nexus 5).
I have switched on the NFC in my watch, but still they don't respond to tags.
Code:
var adapter = tizen.nfc.getDefaultAdapter();
adapter.setPowered(
true, // Enable NFC adapter
function () {console.log('Power on success');}, // Handle succes
function () {console.log('Power on failed');}); // Handle failure
//
var onSuccessCB = {onattach : function(nfcTag) {
console.log("NFC Tag's type is " + nfcTag.type);
navigator.vibrate([600, 100, 300, 200, 0]);
for(var i in nfcTag.properties) {
console.log("key:" + i + " value:" + nfcTag.properties[i]);
}
}, ondetach : function() {
console.log("NFC Tag is detached");
}};
adapter.setTagListener(onSuccessCB);
The NFC API is optional for both Tizen mobile and wearable profiles, which means that it may not be supported in all mobile and wearable devices. The NFC API is supported on the Tizen wearable Emulator, but not on the Tizen mobile Emulator.
Please go through this link for more details.
I've seen some other people having same issue. Have a look on this link too.

Resources