SNS aws not working properly - java

Hello all i wrote an application grabbing photos from facebook. I did that successfully. Now i wrote a notification service using SNS in java. Basically sending out subscription for first time users who log into my application and also when a pictured has been deleted from the repository. My first problem is when i download the pics and user info from facebook, i want to check if its a new user or not. If a new user send out a subscription and if not(basically user exist in mongoDb dont send out email for subscription) but my code keeps sending out email to everyuser. And lastly when a user deletes a photo they get a notification but when i tested it i failed to get an email. Below is my code could someone tell me what im doing wrong.
public class EmailNotifications {
private static final String accessKey = "****************";
private static final String secretAccess ="***********************";
//Notification when user gets info from facebook app for first time.
public static void SignUP(String email, String Topic){
AmazonSNSClient snsClient = new AmazonSNSClient(new BasicAWSCredentials(accessKey, secretAccess));
snsClient.setRegion(Region.getRegion(Regions.US_WEST_1));
//create a Topic
CreateTopicRequest createTopicRequest = new CreateTopicRequest().withName(Topic);
CreateTopicResult createTopicResult = snsClient.createTopic(createTopicRequest);
//subscribes to a topic
SubscribeRequest subscribeRequest = new SubscribeRequest().withTopicArn(createTopicResult.getTopicArn())
.withProtocol("email").withEndpoint(email);
snsClient.subscribe(subscribeRequest);
}
//Notification when photo is deleted
public static void deletePic(String email, String topic, String message){
AmazonSNSClient snsClient = new AmazonSNSClient(new BasicAWSCredentials(accessKey,secretAccess));
snsClient.setRegion(Region.getRegion(Regions.US_WEST_1));
CreateTopicRequest create = new CreateTopicRequest(topic);
CreateTopicResult result = snsClient.createTopic(create);
System.out.println(result);
//String msg = "My text published to SNS topic with email endpoint";
PublishRequest publishRequest = new PublishRequest(result.getTopicArn(), message);
publishRequest.setSubject("Deleted Pic");
/*PublishResult pu= */snsClient.publish(publishRequest);
}
}
Below is my implementation of both delete and grabbing data for first assuming mongodb is empty:
Delete photo implementation:
#Override
//deletes photo from mongoDB... but doesn't send out an email stating phootid
public String deletePhoto(String id, String PhotoId){
String mssg="";
if(accountRepo.exists(id)){
UserAccounts userAccounts=accountRepo.findById(id);
UserPhotos photos = photoRepo.findByPhotoId(PhotoId);
mssg="The picture "+photos.getPhotoId()+" has been deleted from the application";
EmailNotifications.deletePic(userAccounts.getEmail(),topic,mssg);
photoRepo.delete(PhotoId);
return "Photo is deleted";
}
else
return "Photo does not exist";
}
Grabbing photo from face for the first time. The user should get only one notification max. But i keep getting several messages.
#Override
public UserAccounts create(FacebookClient facebookClient){
User me = facebookClient.fetchObject("me", User.class);
UserAccounts userAccounts = new UserAccounts();
userAccounts.setEmail(me.getEmail());
userAccounts.setGender(me.getGender());
userAccounts.setId(me.getId());
userAccounts.setName(me.getName());
accountRepo.save(userAccounts);
EmailNotifications.SignUP(me.getEmail(), topic);
return userAccounts;
}
Could some one assist me on this

Judging by your description and the code, it would guess the email you keep getting when you download for a user is the subscription confirmation email because all EmailNotifications.SignUp does is subscribe the email address.
I would guess that the reason you haven't getting any email when you delete a picture is because you haven't confirmed the subscription. In the subscription confirmation emails, there should be a link you can click on to confirm the subscription.
As for why you keep getting the email every time you download, I can't tell from your code, but in the create method you show there is not if block around calling SignUp to check if the user already existed, which I imagine is your problem.
As an aside, if your application is interacting with users and you want a good email experience, you would probably be better off using SES, which allows you to completely control the formatting and branding of your email.

Related

How to retrieve UID of other users and not the current user? [duplicate]

This question already has answers here:
How to exclude an element from a Firestore query?
(8 answers)
Closed 1 year ago.
I am trying to retrieve UID of all the users except of the current user. I tried to do FirebaseAuth.getInstance().getUid(); but it returns CurrentUserUid. Is there a way for NOT getting UID of the current user?
When you are using your app, you are considered as a normal user and not an admin or privileged user. Client SDKs cannot fetch information about other users. You would have to use a secure environment such as Cloud Functions or your own along with Admin SDK to retrieve information about other users.
You can create a Callable Function that fetched a specific user by email or UID like this:
export const getUser = functions.https.onCall(async (data, context) => {
// Verify if the user requesting data is authorized
const {email} = data;
const userRecord = await admin.auth().getUserByEmail(email)
return userRecord.uid
});
You can then call this function from your Android app like this:
private Task<String> getUserInfo(String userEmail) {
// Create the arguments to the callable function.
Map<String, Object> data = new HashMap<>();
data.put("email", userEmail);
return mFunctions
.getHttpsCallable("getUser")
.call(data)
.continueWith(new Continuation<HttpsCallableResult, String>() {
#Override
public String then(#NonNull Task<HttpsCallableResult> task) throws Exception {
// This continuation runs on either success or failure, but if the task
// has failed then getResult() will throw an Exception which will be
// propagated down.
String result = (String) task.getResult().getData();
return result;
}
});
}
Do note that you must check if the user calling the function and requesting the data is authorized. You can check custom claims, the UID or any identifier that decides who can view others users' information.
If your application requires anyone to view all information, then you would have to use any database that stores users' information and can be fetched on your app because you cannot fetch that data using Client Auth SDK.

carry out firebase authentication from a service class?

I have an activity for new users that consists of 3 edit texts, one for entering their email address, setting their password and entering receipt numbers. Before signing up using firebase users are supposed to pay for services through the banks and use the receipt number to confirm payment in the app, when the user clicks the sign up button the entered receipt number is sent to the private server, which sends back an ID. This all works, but I am trying to send the parsed ID number from the json response along with the users inputed email address and password to a service class, where a sign up method starts after 30 seconds. In the sign up method, the ID is sent to the server for verification and when a valid json response is received from the server, it creates a new firebase user using the string password and email address passed from the main activity. I however get a null pointer error in the same line where the email address and password is put in the firebase create new user method. Below is how I get the email address and password from the main activity
public Signupservice() {
String a;
String b;
}
......
#Override
public int onStartCommand(Intent intent, int flags , int startId){
a=intent.getStringExtra(FILENAMED);
b=intent.getStringExtra(FILEEXD);
......
firebaseAuth.createUserWithEmailAndPassword(a, b).addOnCompleteListener( new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Toast.makeText(getApplicationContext(), "signupunsuccessful: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),"suucessfull",Toast.LENGTH_SHORT).show();
However I receive the following error from the logcat in reference to the first line of code from the method create user with email and password
2019-10-02 20:40:15.539 20184-20184/com.chomba.haroldking.kupa E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.chomba.haroldking.kupa, PID: 20184
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.tasks.Task com.google.firebase.auth.FirebaseAuth.createUserWithEmailAndPassword(java.lang.String, java.lang.String)' on a null object reference
at com.chomba.haroldking.kupa.Signupservice.parseData(Signupservice.java:159)
Below is how string is sent to the service class
Intent startServiceIntent=new Intent(Signupuser.this,Signupservice.class);
startServiceIntent.putExtra(FILENAMED,emailIDfed);
startServiceIntent.putExtra(FILEEX,gce);
startServiceIntent.putExtra(FILENAMEDD,paswdfed);
Please render assistance
firebaseAuth is null. It looks like you have not assigned it before first using it. Make sure to assign it first: firebseAuth = FirebaseAuth.getInstance().

Get user's displayname in firebase function once account is created

I have an Android app where the user registers for an account with their email, password, and displayName. I want to send a welcome email to the user after they create an account. This is how I create my account and set their display name.
// This happens in Android (RegisterActivity.java) where I create user's account
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.createUserWithEmailAndPassword(email, password)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
FirebaseUser user = authResult.getUser();
user.updateProfile(new UserProfileChangeRequest.Builder()
.setDisplayName(name).build());
}
});
Once the user's account is created, a firebase function is triggered. Below is my code:
// This happens in Firebase Cloud Functions (index.js)
exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
// send welcome email here
console.log(user.displayName) // displayName is null here
});
I believe that the firebase function gets triggered as soon as the account creation is successful, and I set user's displayname after the account is created and so displayName is null in the function. What can I do to solve the issue? I don't want to send an email to the user without their name in the email.
tl;dr: displayName is being called before is being set.
The onCreate function runs after the front end finishes createUserWithEmailAndPassword but before the displayName is set.
Either you run an onCall function after you update the displayName or as suggested on the firebase github thread on this issue you can add a profile parameter to the createUserWithEmailAndPassword so that we create new accounts with a pre-populated profile.

How to create unique token, in every users firebase android?

I want to generate and store token everytime users login. I tried for my code below, but it always generate same token when I login with another account.
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
AlertDialog.dismiss();
if (!task.isSuccessful()) {
if (password.length() < 6) {
new SweetAlertDialog(LoginActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("Oops...")
.setContentText("Enter minimum 6 charachters !! ")
.show();
} else {
passwordInput.setText("");
new SweetAlertDialog(LoginActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("Oops...")
.setContentText("Authentication failed !!")
.show();
}
} else {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
FirebaseUser users = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("users/"+ users.getUid());
String token = FirebaseInstanceId.getInstance().getToken();
Log.e("tokenid",""+token);
mDatabase.child("token_id").setValue(token);
finish();
}
}
});
}
});
please help, thanks..
When using the following line of code:
String token = FirebaseInstanceId.getInstance().getToken();
You are getting the Firebase Instance ID token, which is also known as FCM token, on the client side. You need to know that in Firebase there two different tokens:
A FCM Token/Instance ID token that identifies an installation of a specific application on a specific user device. It doesn't identify in any way a particular user.
An Auth ID token identifies a specific user of a specific application. It doesn't identify in any way a particular device.
The two tokens are quite different and serve different purposes. Please see the official documentation for Android regarding on how to retrieve ID tokens on clients.
The identity of the user is remembered indefinitely (or until you sign out). But their credentials (or rather, whether their token is still valid) are re-checked every hour.
FCM generates a registration token for the client app instance, hence It may happen that you'll get the same token for different users in your app. You can use forceRefresh to generate a new token every time. Register new token everytime user logins to any device and save it in DB and update with a new token on new login this way you will have a new token for each user on every login (If this fits your requirement)
Here is a good answer to understand how it works Firebase FCM force onTokenRefresh() to be called
Use UUID.randomUUID().toString()
You can read more here.
java docs - and here =)

Checking for last user that logged in

I am trying to finish up the implementation of a login screen for my app. I have a REST API backend that verifies the username + token and returns the userId of the person logging into the app.
I want to store the last userId from the user who has logged into the app. I plan to use Shared preferences for this.
Based on the last stored userId, i plan to execute either going to the main activity (if this user has logged in previously, but logged out after a while and is re-logging in), or executing an AsynkTask to syncronise some data from the backend (if it is a new user). Here is my logic, which seems to not be working properly.
It is switching directly to the MainSyncTask, even if i'm logging in with the last username (userId is the same, received from the API), and savedUserId.equals(currentUserId) should return true and execute the Intent. last userId is properly store in the sharedpreferences db, check with Stecho .
String userId = getUserIdFromAPIResponse();
sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this);
private void checkIdAndGoToActivity() {
final String PREF_VERSION_CODE_KEY = "user_id";
// Get current version code
String currentUserId = userId;
// Get saved version code
String savedUserId = sharedpreferences.getString(PREF_VERSION_CODE_KEY, "");
if (savedUserId.equals(currentUserId)) {
Log.e(TAG, "Current User Logged in");
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
/* destroys activity , prevents user from going back to previous MainActivity after login out */
finish();
} else if (!savedUserId.equals(currentUserId)) {
Log.e(TAG, "New user logged in");
MainSyncTask mainSyncTask = new MainSyncTask(LoginActivity.this, LoginActivity.this, userEmail, userPassword);
mainSyncTask.execute();
SyncEventReceiver.setupAlarm(getApplicationContext());
}
// Update the shared preferences with the current version code
sharedpreferences.edit().putString(PREF_VERSION_CODE_KEY, currentUserId).apply();
}

Categories

Resources