Okay so after updating to the newest firebase messaging library, I can't seem to retrieve the token. I t said in the docs that it should not be run in the main thread but when I tried, it still didn't work. So I simply removed it. What could I be doing wrong?
Below is my try/catch code.
String device_token;
try {
device_token = FirebaseInstanceId.getInstance().getToken(R.string.sender_id, "FCM");
student_token_reference = FirebaseDatabase.getInstance().getReference().child("MakeUpArtists_Info").child(uid);
student_token_reference.child("device_token").setValue(device_token).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
DatabaseReference check_variablesRef = FirebaseDatabase.getInstance().getReference().child("MakeUpArtists_Info").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("Verification");
check_variablesRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String id_card = dataSnapshot.child("id_card").getValue().toString();
String image = dataSnapshot.child("image").getValue().toString();
if (id_card.equals("Not yet") && image.equals("Not yet")) {
Toast.makeText(LoginActivity.this, "Please finish uploading your documents", Toast.LENGTH_SHORT).show();
Intent id_card_intent = new Intent(LoginActivity.this, IDcard.class);
startActivity(id_card_intent);
finish();
} else if (id_card.equals("Received") && image.equals("Received")) {
Intent intentMain = new Intent(LoginActivity.this, MainActivity.class);
intentMain.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intentMain);
finish();
} else if (id_card.equals("Received") && image.equals("Not yet")) {
Toast.makeText(LoginActivity.this, "Please upload your profile picture", Toast.LENGTH_SHORT).show();
Intent success_intent = new Intent(LoginActivity.this, DisplayProfile.class);
startActivity(success_intent);
finish();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
} catch (IOException e) {
e.printStackTrace();
}
Any help would be greatly appreciated!
The Firebase Release Notes for the June 28 release recommend using FirebaseInstanceId.getInstance().getInstanceId(). Here is an example (as you requested in comments) of how to do that:
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(
new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(Task<InstanceIdResult> task) {
if (task.isSuccessful()) {
final InstanceIdResult iidResult = task.getResult();
final String token = iidResult.getToken();
Log.d(TAG, "token=" + token);
// process token as you need...
} else {
Log.e(TAG, "get IID/token failed", task.getException());
}
}
});
Related
I am developing an app in unity. I use the firebase google login method. basically google login is working and the user was listed in google firebase users log after login. the problem is, it is throwing an error. because of this can't fetch data from the firestore. even without firestore code, the app is showing the error
Got Error: DeveloperError Exception of type
'Google.GoogleSignIn+SignInException' was thrown
what may be the problem.
below is my code
public class GoogleSignInDemo : MonoBehaviour
{
public Text infoText;
private string webClientId = "xxxxxxaaaaaaabbbb.apps.googleusercontent.com";
private FirebaseAuth auth;
private GoogleSignInConfiguration configuration;
private void Awake()
{
configuration = new GoogleSignInConfiguration { WebClientId = webClientId, RequestEmail = true, RequestIdToken = true };
CheckFirebaseDependencies();
}
private void CheckFirebaseDependencies()
{
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
if (task.IsCompleted)
{
if (task.Result == DependencyStatus.Available)
auth = FirebaseAuth.DefaultInstance;
else
AddToInformation("Could not resolve all Firebase dependencies: " + task.Result.ToString());
}
else
{
AddToInformation("Dependency check was not completed. Error : " + task.Exception.Message);
}
});
}
public void SignInWithGoogle() { OnSignIn(); }
public void SignOutFromGoogle() { OnSignOut(); }
private void OnSignIn()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
AddToInformation("Calling SignIn");
GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnAuthenticationFinished);
}
private void OnSignOut()
{
AddToInformation("Calling SignOut");
GoogleSignIn.DefaultInstance.SignOut();
}
public void OnDisconnect()
{
AddToInformation("Calling Disconnect");
GoogleSignIn.DefaultInstance.Disconnect();
}
internal void OnAuthenticationFinished(Task<GoogleSignInUser> task)
{
if (task.IsFaulted)
{
using (IEnumerator<Exception> enumerator = task.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
GoogleSignIn.SignInException error = (GoogleSignIn.SignInException)enumerator.Current;
AddToInformation("Got Error: " + error.Status + " " + error.Message);
}
else
{
AddToInformation("Got Unexpected Exception?!?" + task.Exception);
}
}
}
else if (task.IsCanceled)
{
AddToInformation("Canceled");
}
else
{
AddToInformation("Welcome: " + task.Result.DisplayName + "!");
AddToInformation("Email = " + task.Result.Email);
AddToInformation("Google ID Token = " + task.Result.IdToken);
AddToInformation("Email = " + task.Result.Email);
SignInWithGoogleOnFirebase(task.Result.IdToken);
SceneManager.LoadScene(1); //Savad - Load Welcome screen when Google Login
}
}
private void SignInWithGoogleOnFirebase(string idToken)
{
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
AggregateException ex = task.Exception;
//==============Here is the problem
if (ex != null)
{
if (ex.InnerExceptions[0] is FirebaseException inner && (inner.ErrorCode != 0))
AddToInformation("\nError code = " + inner.ErrorCode + " Message = " + inner.Message);
//=======================================
}
else
{
AddToInformation("Sign In Successful.");
}
});
}
public void OnSignInSilently()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
AddToInformation("Calling SignIn Silently");
GoogleSignIn.DefaultInstance.SignInSilently().ContinueWith(OnAuthenticationFinished);
}
public void OnGamesSignIn()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = true;
GoogleSignIn.Configuration.RequestIdToken = false;
AddToInformation("Calling Games SignIn");
GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnAuthenticationFinished);
}
private void AddToInformation(string str) { infoText.text += "\n" + str; }
public void SwitchToPhoneSignup()
{
SceneManager.LoadScene(2);
}
public void SwitchToOtp()
{
SceneManager.LoadScene(2);
}
public void SwitchToEmailSignUP()
{
SceneManager.LoadScene(2);
}
}
Here is a working example of Google SignIn code w/ Firebase Authentication and GoogleSignIn libraries:
private void SignInWithGoogle(bool linkWithCurrentAnonUser)
{
GoogleSignIn.Configuration = new GoogleSignInConfiguration
{
RequestIdToken = true,
// Copy this value from the google-service.json file.
// oauth_client with type == 3
WebClientId = "[YOUR API CLIENT ID HERE].apps.googleusercontent.com"
};
Task<GoogleSignInUser> signIn = GoogleSignIn.DefaultInstance.SignIn();
TaskCompletionSource<FirebaseUser> signInCompleted = new TaskCompletionSource<FirebaseUser>();
signIn.ContinueWith(task =>
{
if (task.IsCanceled)
{
signInCompleted.SetCanceled();
}
else if (task.IsFaulted)
{
signInCompleted.SetException(task.Exception);
}
else
{
Credential credential = Firebase.Auth.GoogleAuthProvider.GetCredential(((Task<GoogleSignInUser>)task).Result.IdToken, null);
if (linkWithCurrentAnonUser)
{
mAuth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(HandleLoginResult);
}
else
{
SignInWithCredential(credential);
}
}
});
}
The parameter is for signing in with intentions of linking the new google account with an anonymous user that is currently logged on. You can ignore those parts of the method if desired. Please note all of this is called after proper initialization of the Firebase Auth libraries.
Source: https://github.com/googlesamples/google-signin-unity
The readme page contains a step-by-step instructions for getting this setup for your environment. After following those and using the code above, you should have this working on both android and iOS.
Here is the SignInWithCredential method used in the code above:
private void SignInWithCredential(Credential credential)
{
if (mAuth != null)
{
mAuth.SignInWithCredentialAsync(credential).ContinueWith(HandleLoginResult);
}
}
`mAuth` is a reference to FirebaseAuth:
mAuth = Firebase.Auth.FirebaseAuth.DefaultInstance;
For someone asking for the HandleLoginResult from #DIGI Byte, here is the code, feel free to remove try/catch block for debug purpose:
private void HandleLoginResult(Task<FirebaseUser> task)
{
try
{
if (task.IsCanceled)
{
UnityEngine.Debug.LogError("SignInWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
UnityEngine.Debug.LogError("SignInWithCredentialAsync encountered an error: " + task.Exception.InnerException.Message);
return;
}
else
{
FirebaseUser newUser = task.Result;
UnityEngine.Debug.Log($"User signed in successfully: {newUser.DisplayName} ({newUser.UserId})");
}
}
catch (Exception e)
{
if (e != null)
{
UnityEngine.Debug.Log(e.InnerException.Message);
}
}
}
You have Error like: got error developer error exception of type 'google.googlesignin+signin exception' was thrown?
APK and AAB file have different SHA1 and SHA256. In Firebase, it's best to add SHA for both applications.
You can check the SHA from the AAB file in Google Play Console -> Your application -> Configuration -> Application integrity -> Application signing.
I added these SHA keys to Firebase and the problem was gone.
I'm new in xamarin and I want make a phone call directly (without opening the dialler). I tried with this example but it doesn't work.
Click Please help
public class PhoneCall_Droid : IPhoneCall
{
public void MakeQuickCall(string PhoneNumber)
{
try
{
var uri = Android.Net.Uri.Parse(string.Format("tel:{0}", PhoneNumber));
var intent = new Intent(Intent.ActionCall, uri);
Xamarin.Forms.Forms.Context.StartActivity(intent);
}
catch (Exception ex)
{
new AlertDialog.Builder(Android.App.Application.Context).SetPositiveButton("OK", (sender, args) =>
{
//User pressed OK
})
.SetMessage(ex.ToString())
.SetTitle("Android Exception")
.Show();
}
}
}
there are two error in your code above:
1.Xamarin.Forms.Forms.Context could not get the correct context.
you could defined a static variable in MainActiviy like :
public static MainActivity Instance;
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
Instance = this;
LoadApplication(new App());
}
you also could use the Current Activity Plugin,you could refer to Current Activity
2.After Android6.0 you should requests the runtime permissions and the official doucument
here is a simple example:
[assembly: Xamarin.Forms.Dependency(typeof(PhoneCall_Droid))]
namespace App18.Droid
{
class PhoneCall_Droid: IPhoneCall
{
public void MakeQuickCall(string PhoneNumber)
{
try
{
if(ActivityCompat.CheckSelfPermission(MainActivity.Instance, Android.Manifest.Permission.CallPhone) != Android.Content.PM.Permission.Granted ){
ActivityCompat.RequestPermissions(MainActivity.Instance, new string[] {Android.Manifest.Permission.CallPhone }, 1);
return;
}
else
{
var uri = Android.Net.Uri.Parse(string.Format("tel:{0}", PhoneNumber));
var intent = new Intent(Intent.ActionCall, uri);
MainActivity.Instance.StartActivity(intent);
}
}
catch (Exception ex)
{
new AlertDialog.Builder(MainActivity.Instance).SetPositiveButton("OK", (sender, args) =>
{
//User pressed OK
})
.SetMessage(ex.ToString())
.SetTitle("Android Exception")
.Show();
}
}
}
}
and you also could to use the nugetpackage Plugin.Permissions to request runtime permissions(Permission.Location)
refer to Plugin.Permissions
finally you could call like
DependencyService.Get<IPhoneCall>().MakeQuickCall(phonenumber);
I want to show dialogue when new version is available.
I want to make a json file into my web server, and I will manually update my app version in json file. and my app will parse this json file and will notify users and showing dialogue box to update my app from playstore link by clicking Update button.
I don't want to make this with firebase.
public class ForceUpdateAsync extends AsyncTask<String, String, JSONObject>{
private String latestVersion;
private String currentVersion;
private Context context;
public ForceUpdateAsync(String currentVersion, Context context){
this.currentVersion = currentVersion;
this.context = context;
}
#Override
protected JSONObject doInBackground(String... params) {
try
{
latestVersion = Jsoup.connect("https://play.google.com/store/apps/details?id="+context.getPackageName()+"&hl=en")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select("div[itemprop=softwareVersion]")
.first()
.ownText();
} catch (IOException e) {
e.printStackTrace();
}
return new JSONObject();
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
if(latestVersion!=null){
if(!currentVersion.equalsIgnoreCase(latestVersion)){
// Toast.makeText(context,"update is available.",Toast.LENGTH_LONG).show();
if(!(context instanceof SplashActivity)) {
if(!((Activity)context).isFinishing()){
showForceUpdateDialog();
}
}
}
}
super.onPostExecute(jsonObject);
}
public void showForceUpdateDialog(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(new ContextThemeWrapper(context,
R.style.DialogDark));
alertDialogBuilder.setTitle(context.getString(R.string.youAreNotUpdatedTitle));
alertDialogBuilder.setMessage(context.getString(R.string.youAreNotUpdatedMessage) + " " + latestVersion + context.getString(R.string.youAreNotUpdatedMessage1));
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton(R.string.update, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
dialog.cancel();
}
});
alertDialogBuilder.show();
}
}
after that in your splash activity just use this code
public void forceUpdate()
{
PackageManager packageManager = this.getPackageManager();
PackageInfo packageInfo = null;
try {
packageInfo = packageManager.getPackageInfo(getPackageName(),0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
String currentVersion = packageInfo.versionName;
new ForceUpdateAsync(currentVersion,BaseActivity.this).execute();
}
I am trying to load image in my Firebase storage from my database reference. I am then using Picasso (implementation 'com.squareup.picasso:picasso:2.71828') to retrieve the image from the database reference. The entirety of the code I am using can be found here https://github.com/kshitiz1007/Lets-Chat though with updated libraries and slightly update ui. But the two files of note are SettingActivity, where user chooses profile image and text status to put into database and ProfileActivity, where the the profile image is called for use by Picasso.
My understanding is that in SettingActivity, the profile image as well as the thumb size version of the profile image, are being saved to a hashmap in SettingActivity:
update_HashMap.put("image",downloadUrl);
update_HashMap.put("thumb_image",thumb_download_url);
//--------ADDING URL INTO DATABASE REFERENCE-------
mDatabaseReference.updateChildren(update_HashMap).addOnCompleteListener(new
My problem is that calling when Picasso calls load, display image of source (String display_image = dataSnapshot.child("image").getValue().toString();) never loads.
But I do not know the mechanism nor how the image is retrieved from Storage using the Firebase database reference. When Picasso tries to get the image from the database reference it says in Run
Log
D/Picasso: Main created [R22]
Request{com.google.android.gms.tasks.zzu#5843814}
...
D/Picasso: Main errored [R22]+246ms Unrecognized type of request:
Request{com.google.android.gms.tasks.zzu#5843814}
Firebase Database
Firebase Storage
If you view the second picture, the image seems to have a pointer to a task and Picasso doesn't know how to use that information.
Below is from SettingActivity.java
public class SettingActivity extends AppCompatActivity {
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//-----STARTING GALLERY----
if(requestCode == GALLERY_PICK && resultCode == RESULT_OK){
Uri sourceUri = data.getData();
//-------CROPPING IMAGE AND SETTING MINIMUM SIZE TO 500 , 500------
CropImage.activity(sourceUri).
setAspectRatio(1,1).
setMinCropWindowSize(500,500).
start(SettingActivity.this);
}
//------START CROP IMAGE ACTIVITY------
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE ) {
//------CROP IMAGE RESULT------
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
mProgressDialog.setTitle("Uploading Image");
mProgressDialog.setMessage("Please wait while we process and upload the image...");
mProgressDialog.setCancelable(false);
mProgressDialog.setProgress(ProgressDialog.STYLE_SPINNER);
mProgressDialog.show();
Uri resultUri = result.getUri();
File thumb_filepath = new File(resultUri.getPath());
try {
//--------COMPRESSING IMAGE--------
Bitmap thumb_bitmap = new Compressor(this).
setMaxWidth(200).
setMaxHeight(200).
setQuality(75).
compressToBitmap(thumb_filepath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
thumb_bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
thumb_bytes= baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
final StorageReference filepath = mStorageReference.child("profile_image").child(uid+".jpg");
final StorageReference thumb_file_path = mStorageReference.child("profile_image").child("thumbs").child(uid+".jpg");
//------STORING IMAGE IN FIREBASE STORAGE--------
filepath.putFile(resultUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
#SuppressWarnings("VisibleForTests")
final String downloadUrl= filepath.getDownloadUrl().toString();
final UploadTask uploadTask = thumb_file_path.putBytes(thumb_bytes);
//---------- STORING THUMB IMAGE INTO STORAGE REFERENCE --------
uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> thumb_task) {
#SuppressWarnings("VisibleForTests")
String thumb_download_url = uploadTask.getSnapshot().getMetadata().getReference().getDownloadUrl().toString();
// String thumb_download_url = thumb_task.getResult().getDownloadUrl().toString();
if(thumb_task.isSuccessful()){
Map update_HashMap=new HashMap();
// Download Url stored to HashMap but where is this HashMap and how does it reference storage from database
update_HashMap.put("image",downloadUrl);
update_HashMap.put("thumb_image",thumb_download_url);
//--------ADDING URL INTO DATABASE REFERENCE--------
mDatabaseReference.updateChildren(update_HashMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
mProgressDialog.dismiss();
Toast.makeText(SettingActivity.this, "Uploaded Successfuly...", Toast.LENGTH_SHORT).show();
}
else{
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), " Image is not uploading...", Toast.LENGTH_SHORT).show();
}
}
});
}
else{
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), " Error in uploading Thumbnail..", Toast.LENGTH_SHORT).show();
}
}
});
}
else{
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), " Image is not uploading...", Toast.LENGTH_SHORT).show();
}
}
});
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Exception error = result.getError();
}
}
}
}
Below is from ProfileActivity.java
mfriendReqReference = FirebaseDatabase.getInstance().getReference().child("friend_request");
mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("users").child(user_id);
mFriendDatabase = FirebaseDatabase.getInstance().getReference().child("friends");
mNotificationReference = FirebaseDatabase.getInstance().getReference().child("notifications");
mRootReference = FirebaseDatabase.getInstance().getReference();
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
//----fOR SETTING ONLINE---
getmDatabaseReference = FirebaseDatabase.getInstance().getReference().child("users").child(mFirebaseUser.getUid());
mProgressDialog = new ProgressDialog(ProfileActivity.this);
mProgressDialog.setTitle("Fetching Details");
mProgressDialog.setMessage("Please wait...");
mProgressDialog.setProgress(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
mCurrent_state = "not_friends"; // 4 types--- "not_friends" , "req_sent" , "req_received" & "friends"
//----ADDING NAME , STATUS AND IMAGE OF USER----
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String display_name = dataSnapshot.child("name").getValue().toString();
String display_status = dataSnapshot.child("status").getValue().toString();
String display_image = dataSnapshot.child("image").getValue().toString();
mProfileName.setText(display_name);
mProfileStatus.setText(display_status);
Picasso.get()
.load(display_image)
.placeholder(R.drawable.user_img)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(mProfileImage);
// ---------------------------------------------------------------------------------
//https://stackoverflow.com/questions/46071230/use-glide-load-into-imageview-but-delay?rq=1
/*RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.user_img);
Glide.with(ProfileActivity.this)
.setDefaultRequestOptions(requestOptions)
.load(Uri.parse(display_image))
// .placeholder(R.drawable.user_img)
.into(mProfileImage);*/
//----ADDING TOTAL NO OF FRIENDS---
mFriendDatabase.child(user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
long len = dataSnapshot.getChildrenCount();
mprofileFriendCount.setText("TOTAL FRIENDS : "+len);
//----SEEING THE FRIEND STATE OF THE USER---
//----ADDING THE TWO BUTTON-----
mfriendReqReference.child(mFirebaseUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//----CHECKING IF FRIEND REQUEST IS SEND OR RECEIVED----
if(dataSnapshot.hasChild(user_id)){
String request_type = dataSnapshot.child(user_id).child("request_type").getValue().toString();
if(request_type.equals("sent")){
mCurrent_state="req_sent";
mProfileSendReqButton.setText("Cancel Friend Request");
mProfileDeclineReqButton.setVisibility(View.INVISIBLE);
mProfileDeclineReqButton.setEnabled(false);
}
else if(request_type.equals("received")){
mCurrent_state="req_received";
mProfileSendReqButton.setText("Accept Friend Request");
mProfileDeclineReqButton.setVisibility(View.VISIBLE);
mProfileDeclineReqButton.setEnabled(true);
}
mProgressDialog.dismiss();
}
//---USER IS FRIEND----
else{
mFriendDatabase.child(mFirebaseUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mProfileDeclineReqButton.setVisibility(View.INVISIBLE);
mProfileDeclineReqButton.setEnabled(false);
if(dataSnapshot.hasChild(user_id)){
mCurrent_state="friends";
mProfileSendReqButton.setText("Unfriend This Person");
}
mProgressDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
mProgressDialog.dismiss();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(ProfileActivity.this, "Error fetching Friend request data", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Correct way of getting downloadUrl after uploading here
I use the Google Photo app to pick gallery photo and then when I crop the picture and save, it catches an exception, Here is my code :
goto_picture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
IMAGE_UNSPECIFIED);
startActivityForResult(intent, PHOTO_ZOOM);
dialog.cancel();
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PHOTO_GRAPH) {
startPhotoZoom(Uri.fromFile(file));
String imagePath = SystemUtils.getSDPath() + "/temp.jpg";
File picture = new File(imagePath);
if (picture.exists()) {
pictureBitmap = BitmapFactory.decodeFile(imagePath);
ImageUtils.SaveCacheBitmap(pictureBitmap);
rvEditAvatar.setImageBitmap(pictureBitmap);
}
}
if (requestCode == PHOTO_ZOOM) {
startPhotoZoom(data.getData());
}
if (requestCode == PHOTO_RESULT) {
Bundle extras = data.getExtras();
if (extras != null) {
pictureBitmap = extras.getParcelable("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 100,
stream);
ImageUtils.SaveCacheBitmap(pictureBitmap);
rvEditAvatar.setImageBitmap(pictureBitmap);
}
}
}
}
public void startPhotoZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 180);
intent.putExtra("outputY", 180);
intent.putExtra("return-data", true);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, PHOTO_RESULT);
}
Logcat:
Process: com.google.android.apps.photos, PID: 7031
java.lang.RuntimeException: Unable to resume activity
{com.google.android.apps.photos/com.google.android.apps.photos.photoeditor.intents.EditActivity}:
java.lang.UnsupportedOperationException: No 'output' extra specified
and can not save to specified inputUri:
content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F72072/ACTUAL
As the exception said, you have to specify output extra like the following code.
intent.putExtra(MediaStore.EXTRA_OUTPUT, someOutPutPath);
And return data is not secure in case of big image cropped which may cause crash. I think that's why it forces you to use an output extra but not the data directly. So you may set the return-data to false as well:
intent.putExtra("return-data", false);
I meet this problem today, and solved by double check the data pass-back.I test following code on both Android L and Android 4. On Android L the fileUri is not empty while pre Android L we got fileUri null(in this case, I got the bitmap by simply getData).
private Bitmap decodeBitmapFromCrop(Intent data) {
Bundle extras = data.getExtras();
Bitmap photo = null;
if (extras != null) {
photo = extras.getParcelable("data");
} else {
Uri fileUri = data.getData();
if (fileUri != null) {
try {
photo = MediaStore.Images.Media.getBitmap(getContentResolver(), fileUri);
} catch (IOException e) {
XXLog.d(TAG, "Media.getBitmap", e);
}
}
}
return photo;
}