I set up FCM for my app. And it works perfectly for devices run under Android 11 and less. But for devices under Android 12 and greater I can't receive token by using
FirebaseMessaging.getInstance().token.addOnCompleteListener {
...
}
I receive an error: java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: AUTHENTICATION_FAILED instead of token
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.boltic28.learnmultiplying">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.LearnMultiplying"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".services.firebase.AppFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id" />
</application>
</manifest>
app:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.google.gms.google-services'
}
android {
compileSdk 33
defaultConfig {
applicationId "com.boltic28.learnmultiplying"
minSdk 26
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
...
}
dependencies {
...
implementation 'com.google.firebase:firebase-messaging:23.0.4'
...
}
service:
class AppFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
println("->> new token: $token")
}
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
println("->> new message: ${message.notification?.title} - ${message.notification?.body}")
}
}
Does anybody have some suggestions?
Data:
App targeted: SDK33
Run under : SDK31
FCM version : 23.0.6
The issue was with an emulator, FCM doesn't provide a token for devices under SDK31+ without Google play services. To solve the issue and get a token you have to use an emulator or device with installed Google play services, Google APIs are not enough.
I have an ASP.NET Core Web API with a SignalR hub.
My Program.cs has
builder.Services.AddAuthentication("MyScheme")
.AddCertificate(opt => opt.AllowedCertificateTypes = CertificateTypes.All)
.AddCookie("MyScheme", options =>
{
options.AccessDeniedPath = "/Home/Error";
options.LoginPath = "/Home/Login/";
});
builder.Services.AddSignalR();
builder.WebHost.UseKestrel(options =>
{
options.AddServerHeader = false;
options.Listen(IPAddress.Loopback, 8080, listenOptions =>
{
listenOptions.UseHttps(certificate);
});
})
.ConfigureKestrel(o =>
{
o.ConfigureHttpsDefaults(o =>
o.ClientCertificateMode =
ClientCertificateMode.RequireCertificate);
})
.UseIISIntegration()
.UseUrls("https://*:8080");
app.MapHub<EPSHub>("/TESTHub", options => {
options.Transports = HttpTransportType.WebSockets;});
My web.config looks like this:
<system.webServer>
<handlers>
<remove name="aspNetCore"/>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
<security>
<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
<authentication>
<windowsAuthentication enabled="false" />
<anonymousAuthentication enabled="false" />
<digestAuthentication enabled="false" />
<basicAuthentication enabled="false" />
<iisClientCertificateMappingAuthentication enabled="true" />
</authentication>
<requestFiltering>
<!-- This will handle requests up to 1GB -->
<requestLimits maxAllowedContentLength="52428800" />
</requestFiltering>
</security>
</system.webServer>
My TESTHub.cs has a method OnConnectedAsync where I try to get the client certificate:
public override async Task OnConnectedAsync()
{
var httpCtx = Context.GetHttpContext();
IHttpContextFeature feature = (IHttpContextFeature)this.Context.Features[typeof(IHttpContextFeature)];
HttpContext cntx = feature.HttpContext;
if (httpCtx.Connection.ClientCertificate is null)
{
var result = await httpCtx.Connection.GetClientCertificateAsync();
}
}
But result always is null.
My client app is a WPF application using AspNetCore.Client.
HubConnection.cs has method:
private async Task StartConnection(string url)
{
string certificate = #"C:\test\Certificate.pfx";
var cert = new X509Certificate2(certificate, "1234", X509KeyStorageFlags.MachineKeySet);
Console.WriteLine("cert private key: " + cert.PrivateKey);
var hubConnection = new HubConnectionBuilder()
.WithUrl($"{url}TESTHub", options =>
{
options.ClientCertificates.Add(cert);
})
.Build();
try
{
await hubConnection.StartAsync();
if ((HubProvider.Connection is null ||
HubProvider.Connection.State == HubConnectionState.Disconnected) &&
hubConnection.State == HubConnectionState.Connected)
{
HubClientModel.ConnectAsync(hubConnection);
_isConnectionExist = true;
HubProvider.ServerURI = url;
return;
}
}
}
Has anyone dealt with this problem using SignalR in .NET 6 projects before?
I suggest my API need some additional configure for SignalR client certificates. But all my attempts for resolve this problem have not been successful
I recently published by app in play store. It was not receiving fcm push notification (provided I'm using default channel in fcm console) but receiving fcm test notification to the same device.
The debug version of the app was receiving fcm notifications normally and also receiving fcm test notifications normally.
Please correct any changes in code !
Thanks in Advance !
Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.chillmonk2.mycollege"
android:versionCode="1"
android:versionName="Release">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/icon_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/icon_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="#style/AppTheme">
<activity android:name=".HomeActivity"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:theme="#style/AppTheme">
</activity>
<activity
android:name=".EditProfile"
android:theme="#style/AppTheme"></activity>
<activity
android:name=".ShowProfileActivity"
android:theme="#style/AppTheme"></activity>
<activity
android:name=".SettingsActivity"
android:theme="#style/AppTheme"></activity>
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/rvr" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorAccent" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id"/>
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
</application>
</manifest>
MyFirebaseMessagingService.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
showNotification(remoteMessage.getNotification().getBody());
}
private void showNotification(String body) {
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
Notification notification = new NotificationCompat.Builder(this,getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.rvr)
.setContentTitle("RVRJC")
.setSound(uri)
.setContentText(body)
.setContentIntent(pi)
.setAutoCancel(true)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
#Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.d("FCM Token", "Refreshed token: " + s);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
}
}
build.gradle app
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.github.chillmonk2.mycollege"
minSdkVersion 16
targetSdkVersion 29
versionCode 3
versionName "1.5.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resConfigs "en"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
shrinkResources false
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.multidex:multidex:2.0.0'
implementation 'com.google.firebase:firebase-core:16.0.9'
implementation 'com.google.firebase:firebase-auth:17.0.0'
implementation 'com.google.firebase:firebase-database:17.0.0'
implementation 'com.google.firebase:firebase-firestore:19.0.0'
implementation 'com.google.firebase:firebase-messaging:19.0.1'
implementation 'com.firebaseui:firebase-ui-auth:5.0.0'
implementation 'com.firebaseui:firebase-ui-database:5.0.0'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'org.jsoup:jsoup:1.10.3'
implementation 'androidx.vectordrawable:vectordrawable:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
}
apply plugin: 'com.google.gms.google-services'
com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true
Build.gradle project File
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
maven {
url 'https://maven.fabric.io/public'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.google.gms:google-services:4.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
//crashlytics Plugin
classpath 'io.fabric.tools:gradle:1.29.0'
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
I want to call web service in project (but in same solution) from myClient project.
I have added service reference in myClient project.
When I call scf from code behind it, works but when I try to call it from JavaScript using JSON, I am unable to do so. Guys pls help.
"http://someurl.com/MyWebService.svc/DoWork/" is path of my Service
abovive url someurl is url of localhost
This code is from a.aspx of client application of JSON,
$.ajax(
{
type: 'GET',
url: 'http://someurl.com/MyWebService.svc/DoWork/',
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
error: function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
alert(jqXHR.responseText);
},
success: function (data) {
alert(data);
}
});
From Code behind
string postData = "http://someurl.com/MyWebService.svc/DoWork/";
int timeout = 10;
//string dwml = string.Empty;
//MyServiceReference.MyWebServiceClient ms = new MyServiceReference.MyWebServiceClient();
//dwml = ms.DoWork();
//System.Net.WebClient webClient = new System.Net.WebClient();
//dwml = webClient.DownloadString(serviceURL);
//Response.Write(dwml);
HttpWebRequest webRequest = (HttpWebRequest)System.Net.WebRequest.Create(postData);
// Set the Method property of the request to POST.
webRequest.Headers.Clear();
webRequest.AllowAutoRedirect = true;
webRequest.Timeout = 1000 * timeout;
webRequest.PreAuthenticate = true;
webRequest.ContentType = "application / x - www - form - urlencoded";
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
webRequest.Timeout = 150000;
// Create POST data and convert it to a byte array.
WebResponse webResponse = null;
StreamReader objSR;
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
Stream objStream;
string sResponse;
webResponse = (HttpWebResponse)webRequest.GetResponse();
objStream = webResponse.GetResponseStream();
objSR = new StreamReader(objStream, encode, true);
//<<sResponse doesn't contain Unicode char values>>
sResponse = objSR.ReadToEnd();
Response.Write(sResponse); // OR Response.write(HttpUtility.HtmlEncode(sResponse))
Guys this immediate second question (both asked by me only) which only myself has answered or commented. I got ans 4 this from stack overflows old question
Basic example of using .ajax() with JSONP?
Issue was with cross domain web-service call is not allowed through AJAX.
I came across new concept of JSONP, wow feeling great!
But I was expecting quick reply from Stack overflows other members.
I will not be able to rescue myself every time friends!
calling WCF service from RESTclient in different solution without JSONP:
Here I came up with another working solution for, calling WCF service from RESTclient in different solution without using JSONP i.e. Enabling CORS of service (Cross Origin Resource Sharing) policy.
We all must have tried:
Adding Header Access-Control-Allow-Origin in web-config file of Service Project,
Code in web-config :
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>
but anyhow, that didn't worked out for me!
So, there is another way to achieve the same, is to Create a Global.asax in Service Project and Add this code to the Global.asax.cs:
Code in Global.asax.cs :
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
And you can continue with your regular AJAX call from RESTclient solution to WCF service:
Sample AJAX :
$(document).ready(function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://localhost:51058/Service1.svc/GetData",
dataType: 'json',
success: function (data) {
//do success part here
alert(data);
},
error: function (e) {
alert(e.message);
}
});
});
The best part is, no need to do any modifications in RESTclient project solution.
here I have tried so far
SVC code file service1.svc.cs :
using System;
namespace TestConnection
{
public class Service1 : IService1
{
public string GetData()
{
return string.Format("You entered: {0}", "Success");
}
}
}
JavaScript function:
<script type="text/javascript">
$(document).ready(function () {
var text;
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: 'Service1.svc/GetData', /*you .svc address : 'http://someurl.com/MyWebService.svc/DoWork/'*/
dataType: "json",
async: false,
success: function (a) {
var response = $.parseJSON(a);
text = response.Table[0];
alert(text);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Failure');
}
});
});
</script>
All above code you might have tried, some important note to get this worked is:
1. as WCF .svc works on Representational State Transfer (REST), you have to explicitly mention data get request in service1.svc Markup file,
[OperationContract]
[WebGet()]
//You can use below attributes to make necessary modifications
//RequestFormat = WebMessageFormat.Json,
//ResponseFormat = WebMessageFormat.Json,
//BodyStyle = WebMessageBodyStyle.Bare,
//UriTemplate= "GetData"
//)]
string GetData();
To use WebGet,you will need to add library System.ServiceModel.Web to your service Project.
And if you have issues with basic settings then,
Web.Config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMathService" />
</basicHttpBinding>
</bindings>
</system.serviceModel>
NOTE: This will not work for cross domain, if you want that, its answered Here.
I have done some changes and now getting 415 Unsupported Media Type.
I am posting the updated code.
My Web Service Interface.
Service/IWebService.cs
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle=WebMessageBodyStyle.Wrapped,
RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json,
UriTemplate = "http://localhost:50571/Service/WebService.svc/hello/say")]
string hello(Deneme deneme );
[DataContract]
public class Deneme
{
[DataMember]
public string say { get; set; }
}
My Web Service.
Service/WebService.svc
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WebService : IWebService
{
public string hello(Deneme deneme) {
return deneme.say;
}
Client Side Code.
in Login.aspx
$.ajax({
type: 'POST',
url: '/Service/WebService.svc/hello',
data: { 'say': 'sdfs' },
contentType: 'application/json; charset=utf-8',
dataType:'json',
success: function (s) {
alert(s.d);
}
});
Web Config
<system.serviceModel>
<services>
<service name="TETP.Service.WebService">
<endpoint address=""
behaviorConfiguration=""
binding="basicHttpBinding"
contract="TETP.Service.IWebService" />
</service>
</services>
<behaviors>
<serviceBehaviors >
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
<client>
<endpoint address="http://localhost:50571/Service/WebService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IWebService" contract="TETP.Service.IWebService" name="BasicHttpBinding_IWebService" />
</client>
i used to get 400 bad request error. Now i get 415 Unsupported Media Type error Thank you in advance.
I think you data request might need quotes differently than what you tried but I am not sure. I would suggest adding an alert of your data before the call to debug it. See below..
var mData = "{userName:'" + $('#usernametxtbx').val() + "',password:'" + $('#passwordtxtbx').val() + "'}";
alert(mData);
$.ajax({
type: 'GET',
url: 'Service/WebService.svc/Login',
data:{userName:$('#usernametxtbx').val(),password:$('#passwordtxtbx').val()},
dataType: 'application/json; content=utf-8',
contentType: 'json',
success: function (res) {
if(res.d == true)
window.location.replace(ResolveUrl('Default.aspx'));
else
window.location.replace(ResolveUrl('Login.aspx'));
}
});