Cant unscribe firebase cloud messaging android - android

Sorry for my english. I try use FCM for my test application, everething work fine i use documentation, and in this documentation write if you want unsubscribe from topik use unsubscribeFromTopic, and i use it like this:
public void unscribeChannel(final String chanel) {
FirebaseMessaging.getInstance().unsubscribeFromTopic("/topics/topik" + chanel);
}
but after this nothink happens, I still get notifications(
Then i try delete token like this:
FirebaseInstanceId.getInstance().deleteToken(getToken(), "/topics/topik" + chanel);
but i think it not good and it not help me too

Just write the topic without slashes, like this :
FirebaseMessaging.getInstance().unsubscribeFromTopic("topic_name_only_no_slashes");
Example :
Update:
You can get list of topics of a user using this:
HTTP GET Request
https://iid.googleapis.com/iid/info/<TOKEN>?details=true
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Related

Deleting a user from Azure Active Directory B2C Android/Java

I have an Android application in which I'm using Azure AD B2C to authenticate users. Users login and logout of the application as needed. I would like to give the user the option to delete their own account.
I understand that I need to use the Azure AD Graph API to delete the user. This is what I have so far:
According to this link, it looks like deleting a user from a personal account (which is what the B2C users are using) is not possible. Is that correct?
Here's my code snippet for the Graph API call. Feel free to ignore it if I'm off track and there is a better way to solve this.
I believe I need a separate access token than what my app currently has (as the graph API requires other API consent). So, I'm getting the access token as follows:
AcquireTokenParameters parameters = new AcquireTokenParameters.Builder()
.startAuthorizationFromActivity(getActivity())
.fromAuthority(B2CConfiguration.getAuthorityFromPolicyName(B2CConfiguration.Policies.get("SignUpSignIn")))
.withScopes(B2CConfiguration.getGraphAPIScopes())
.withPrompt(Prompt.CONSENT)
.withCallback(getGraphAPIAuthCallback())
.build();
taxApp.acquireToken(parameters);
In the getGraphAPIAuthCallback() method, I'm calling the Graph API using a separate thread (in the background):
boolean resp = new DeleteUser().execute(authenticationResult.getAccessToken()).get();
Finally, in my DeleterUser() AsyncTask, I'm doing the following:
#Override
protected Boolean doInBackground(String... aToken) {
final String asToken = aToken[0];
//this method will be running on background thread so don't update UI from here
//do your long running http tasks here,you dont want to pass argument and u can access the parent class' variable url over here
IAuthenticationProvider mAuthenticationProvider = new IAuthenticationProvider() {
#Override
public void authenticateRequest(final IHttpRequest request) {
request.addHeader("Authorization",
"Bearer " + asToken);
}
};
final IClientConfig mClientConfig = DefaultClientConfig
.createWithAuthenticationProvider(mAuthenticationProvider);
final IGraphServiceClient graphClient = new GraphServiceClient.Builder()
.fromConfig(mClientConfig)
.buildClient();
try {
graphClient.getMe().buildRequest().delete();
} catch (Exception e) {
Log.d(AccountSettingFragment.class.toString(), "Error deleting user. Error Details: " + e.getStackTrace());
}
return true;
}
Currently, my app fails when trying to get an access token with a null pointer exception:
com.microsoft.identity.client.exception.MsalClientException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
Any idea what I need to do to provide the user the option to users to delete their own account? Thank you!
Thanks for the help, #allen-wu. Due to his help, this azure feedback request and this azure doc, I was able to figure out how to get and delete users silently (without needing intervention).
As #allen-wu stated, you cannot have a user delete itself. So, I decided to have the mobile app call my server-side NodeJS API when the user clicks the 'Delete Account' button (as I do not want to store the client secret in the android app) and have the NodeJS API call the Azure AD endpoint to delete the user silently. The one caveat is that admin consent is needed the first time you try to auth. Also, I have only tested this for Graph API. I'm not a 100% sure if it works for other APIs as well.
Here are the steps:
Create your application in your AAD B2C tenant. Create a client secret and give it the following API permissions: Directory.ReadWrite.All ;
AuditLog.Read.All (I'm not a 100% sure if we need the AuditLog permission. I haven't tested without it yet).
In a browser, paste the following link:
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
Login using an existing admin account and provide the consent to the app.
Once you've given admin consent, you do not have to repeat steps 1-3 again. Next, make the following call to get an access token:
POST https://login.microsoftonline.com/{B2c_tenant_name}.onmicrosoft.com/oauth2/v2.0/token
In the body, include your client_id, client_secret, grant_type (the value for which should be client_credentials) and scope (value should be 'https://graph.microsoft.com/.default')
Finally, you can call the Graph API to manage your users, including deleting them:
DELETE https://graph.microsoft.com/v1.0/users/{upn}
Don't forget to include the access token in the header. I noticed that in Postman, the graph api had a bug and returned an error if I include the word 'Bearer' at the start of the Authorization header. Try without it and it works. I haven't tried it in my NodeJS API yet, so, can't comment on it so far.
#allen-wu also suggested using the ROPC flow, which I have not tried yet, so, cannot compare the two approaches.
I hope this helps!
There is a line of code: graphClient.getUsers("").buildRequest().delete();
It seems that you didn't put the user object id in it.
However, we can ignore this problem because Microsoft Graph doesn't allow a user to delete itself.
Here is the error when I try to do it.
{
"error": {
"code": "Request_BadRequest",
"message": "The principal performing this request cannot delete itself.",
"innerError": {
"request-id": "8f44118f-0e49-431f-a0a0-80bdd954a7f0",
"date": "2020-06-04T06:41:14"
}
}
}

Android - ConsentInformation - Could not parse Event FE preflight response

I ve seen this error posted in many places but no one has ever answered what needs to be done to fix it or why is it happening. I m hoping I ll have better luck.
ConsentInformation consentInformation = ConsentInformation.getInstance(getActivity());
String[] publisherIds = {"pub-**********~*******"};
consentInformation.requestConsentInfoUpdate(publisherIds, new ConsentInfoUpdateListener() {
#Override
public void onConsentInfoUpdated(com.google.ads.consent.ConsentStatus consentStatus) {
//do something
}
#Override
public void onFailedToUpdateConsentInfo(String errorDescription) {
Log.e("GDPR ", errorDescription);
}
});
This is how I am using the consent sdk. I always get the same error: Could not parse Event FE preflight response
My import in gradle is implementation 'com.google.android.ads.consent:consent-library:1.0.6'
I am running this code on the OnCreateView method of the first fragment loaded. Also tried running a few seconds later in case it was a timing thing...still the same error.
Also tried adding the ca-app- prefix before the pub in publisher id...same result.
Any help is appreciated.
Make sure that you're using Publisher ID and not App ID
Publisher ID is the unique identifier for your AdMob account.
Looks something like this pub-7100389293873601
App ID is the unique ID assigned to your app. It looks something like this ca-app-pub-7100382293173983~6849306728.
You can have multiple App IDs (for each app) but you can only have one Publisher ID for your account.
You can find your publisher ID in you AdMob Settings:
Or make sure you pasted it correctly.
Hope this helps!
The Admob account I used was completely new and the "Could not parse Event FE preflight response" was displayed repeatedly. Only when I tried it with an older account it worked. I think you have to wait a bit for verification.
or
Another thing to try is add your payment information to your Admob account
like described in this answer https://stackoverflow.com/a/61423243/8779275 and also check the other points there.

Parse for Android: ParseInstallation.getCurrentInstallation().get(KEY_DEVICE_TOKEN) returns null

Parse for Android: Trying to get a device token in Parse but it keeps returning null. This code was working about 6 months back but lately have noticed this issue. Using the device token to subscribe to Parse later on. It just gets stuck in the while loop.I am using Parse 1.7.1 version. Even if I update the parse will this be the right way to get the device token?
private static final String KEY_DEVICE_TOKEN = "deviceToken";
boolean isTokenReady = false;
while (!isTokenReady) {
String deviceToken = (String) ParseInstallation.getCurrentInstallation().get(KEY_DEVICE_TOKEN);
if (!StringHelper.isNullOrEmpty(deviceToken)) {
isTokenReady = true;
} else {
sleep(1000);
}
}
ParsePush.subscribeInBackground("pushtoken_" + deviceToken);
You can use this, if you are retrieving a String:
ParseInstallation.getQuery().get(objectId).getString(KEY_DEVICE_TOKEN)
If you need to get the objectId from the default installation class:
ParseInstallation.getCurrentInstallation().getObjectId();
I'm using version 1.9.2. Hope this helps!
There's been 11 updates of the Android parse sdk. I would definitely update since there's lots of fixes.
Also, you shouldn't have to block your thread to wait for the device token. Did you forgot to save the installation before trying to get the deviceToken?
Like this:
ParseInstallation.getCurrentInstallation().save();
String deviceToken = (String) ParseInstallation.getCurrentInstallation().get( "deviceToken" );
Lastly, Im not sure why you would use a unique device token as push channels. You can use the deviceToken directly. So I would suggest not to subscribe to any channels and push notifications to selected devices using their deviceTokens.
I spent a lot of time on this problem too...
getInstallationId() seems to work. I use installationId to query installations and now it works OK

Cross platform (iOS-Android) xmpp request

I am creating one chatting application which will work on both iOS and Android platform. Sometimes 'both' subscription is not received at both end. Can anyone tell me what can be the possible issue?
===================== For iOS =====================
Sending request,
XMPPJID *XMPPJIDObj=[XMPPJID jidWithString:aStrOtherJabberId];
[appDelegateObj.xmppRoster addUser:XMPPJIDObj withNickname:nil];
Accepting request,
[appDelegateObj.xmppRoster acceptPresenceSubscriptionRequestFrom:aReceiverJID andAddToRoster:TRUE];
Removing user,
[appDelegateObj.xmppRoster removeUser:[XMPPJID jidWithString:aPresenceObj.userJabberID]];
===================== For Android =====================
Sending request,
Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
myApp.getXmppConnection().getRoster().createEntry(visitorJabberId, visitorUserName, null);
Accepting request,
final Presence presence1 = new Presence(Type.subscribed);
presence1.setFrom(myApp.getUserJabberId());
presence1.setType(Type.subscribed);
presence1.setTo(visitorJabberId);
myApp.getXmppConnection().sendPacket(presence1);
myApp.getXmppConnection().getRoster().createEntry(visitorJabberId, visitorUserName, null);
Removing user,
final RosterPacket rosterPacket = new RosterPacket();
rosterPacket.setType(IQ.Type.SET);
final RosterPacket.Item item = new RosterPacket.Item(visitorJabberId, null);
item.setItemType(RosterPacket.ItemType.remove);
rosterPacket.addRosterItem(item);
myApp.getXmppConnection().sendPacket(rosterPacket);
Hi Leena for the iOS we have used save thing but I think you have forgot some thing. The actual flow is call add user method of roster class then call subscribe method with subscription value YES and finally send presence tag with subscribe type to the serve. Following are the code here I used XMPPSharedPreference singleton class rather than appdelegate. Hope this will work for you...
XMPPJID *newBuddy = [XMPPJID jidWithString:JIDString];
[[XMPPSharedPreference sharedPreferences].xmppRoster addUser:newBuddy withNickname:#"nicknameValue"];
[[XMPPSharedPreference sharedPreferences].xmppRoster acceptPresenceSubscriptionRequestFrom:newBuddy andAddToRoster:YES];
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[presence addAttributeWithName:#"to" stringValue:JIDString];
[presence addAttributeWithName:#"type" stringValue:#"subscribe"];
[[self xmppStream] sendElement:presence];
When you add a user to your roster you have to make sure you also subscribe to the friend's presence. That completes the cycle.
So, for iOS for example, you're adding a friend to roster like this:
[appDelegateObj.xmppRoster addUser:XMPPJIDObj withNickname:nil];
But you need to do use this instead:
- (void)addUser:(XMPPJID *)jid withNickname:(NSString *)optionalName groups:(NSArray *)groups subscribeToPresence:(BOOL)subscribe
and make sure you set subscribe to YES
Or, you could keep the code you have but manually subscribe to the user's presence by doing this:
[appDelegateObj.xmppRoster subscribePresenceToUser:XMPPJIDObj]
Let me know how that works out for you.

getEntity call results in crash (using odata4j on a WCF service)

I am trying out odata4j in my android app to retrieve data from a DB that can be accessed from a WCF service.
ODataConsumer co = ODataConsumer.create("http://xxx.xx.xx.xxx:xxxx/Users");
for(OEntity user : co.getEntities("Users").execute())
{
// do stuff
}
However this crashes at the call to getEntities. I have tried a variety of other calls as well, such as
Enumerable<OEntity> eo = co.getEntities("Users").execute();
OEntity users = eo.elementAt(0);
However this also crashes at eo.elementAt(0).
The logcat doesn't tell me anything, and the callstack seems to be Suspended at ActivityThread.performLaunchActivity.
Entering "http://localhost:xxxx/Users" in my web browser on the other hand works as expected and returns the users in my DB in xml format.
Any ideas on how I can debug this?
To log all http requests/responses:
ODataConsumer.dump.all(true);
The uri passed to the consumer .create call should be the service root. e.g. .create("http://xxx.xx.xx.xxx:xxxx/"); Otherwise your code looks fine.
Note the Enumerable behaves like the .net type - enumeration is deferred until access. If you plan on indexing multiple times into the results, I'd suggest you call .toList() first.
Let me know what you find out.
Hope that helps,
- john
I guess the call should be:
ODataConsumer co = ODataConsumer.create("http://xxx.xx.xx.xxx:xxxx");
for(OEntity user : co.getEntities("Users").execute())
{
// do stuff
}
create defines service you want to connect but Users is the resource you want to query.
Can you try this way.
OEntity oEntity;
OQueryRequest<OEntity> oQueryRequest= oDataJerseyConsumer.getEntities(entityName);
List<OEntity> list= oQueryRequest.execute().toList();
for (OEntity o : list) {
List<OProperty<?>> props = o.getProperties();
for (OProperty<?> prop : props) {
System.out.println(prop.getValue().toString());
}
}

Categories

Resources