Cloud Firestore Security Rules permission - java

How can I log user information into databases and enable user permissions to write to databases during registration.
service cloud.firestore {
match /databases/{database}/documents {
match /Users/{userId} {
// Anybody can write to their ouser doc
allow read, write: if request.auth.uid == userId;
}
}
}
I can not register the user with these restrictions, how can I set good restrictions to enable logging information after confirmation email?
register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (imageUri != null) {
username_ = username.getText().toString();
name_ = name.getText().toString();
email_ = email.getText().toString();
pass_ = password.getText().toString();
location_ = location.getText().toString();
mDialog.show();
if (TextUtils.isEmpty(username_)) {
AnimationUtil.shakeView(username, RegisterActivity.this);
mDialog.dismiss();
}
if (TextUtils.isEmpty(name_)) {
AnimationUtil.shakeView(name, RegisterActivity.this);
mDialog.dismiss();
}
if (TextUtils.isEmpty(email_)) {
AnimationUtil.shakeView(email, RegisterActivity.this);
mDialog.dismiss();
}
if (TextUtils.isEmpty(pass_)) {
AnimationUtil.shakeView(password, RegisterActivity.this);
mDialog.dismiss();
}
if (TextUtils.isEmpty(location_)) {
AnimationUtil.shakeView(location, RegisterActivity.this);
mDialog.dismiss();
}
if (!TextUtils.isEmpty(name_) || !TextUtils.isEmpty(email_) ||
!TextUtils.isEmpty(pass_) || !TextUtils.isEmpty(username_) || !TextUtils.isEmpty(location_)) {
firebaseFirestore.collection("Usernames")
.document(username_)
.get()
.addOnSuccessListener(new OnSuccessListener < DocumentSnapshot > () {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (!documentSnapshot.exists()) {
registerUser();
} else {
Toast.makeText(RegisterActivity.this, "Username already exists", Toast.LENGTH_SHORT).show();
AnimationUtil.shakeView(username, RegisterActivity.this);
mDialog.dismiss();
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e("Error", e.getMessage());
}
});
} else {
AnimationUtil.shakeView(username, RegisterActivity.this);
AnimationUtil.shakeView(name, RegisterActivity.this);
AnimationUtil.shakeView(email, RegisterActivity.this);
AnimationUtil.shakeView(password, RegisterActivity.this);
AnimationUtil.shakeView(location, RegisterActivity.this);
mDialog.dismiss();
}
} else {
AnimationUtil.shakeView(profile_image, RegisterActivity.this);
Toast.makeText(RegisterActivity.this, "We recommend you to set a profile picture", Toast.LENGTH_SHORT).show();
mDialog.dismiss();
}
}
});
}
Registering a user
private void registerUser() {
mAuth.createUserWithEmailAndPassword(email_, pass_).addOnCompleteListener(new OnCompleteListener < AuthResult > () {
#Override
public void onComplete(#NonNull final Task < AuthResult > task) {
if (task.isSuccessful()) {
Map < String, Object > usernameMap = new HashMap < String, Object > ();
usernameMap.put("username", username_);
firebaseFirestore.collection("Usernames")
.document(username_)
.set(usernameMap)
.addOnSuccessListener(new OnSuccessListener < Void > () {
#Override
public void onSuccess(Void aVoid) {
task.getResult()
.getUser()
.sendEmailVerification()
.addOnSuccessListener(new OnSuccessListener < Void > () {
#Override
public void onSuccess(Void aVoid) {
final String userUid = task.getResult().getUser().getUid();
final StorageReference user_profile = storageReference.child(userUid + ".png");
user_profile.putFile(imageUri).addOnCompleteListener(new OnCompleteListener < UploadTask.TaskSnapshot > () {
image upload
#Override
public void onComplete(#NonNull final Task < UploadTask.TaskSnapshot > task) {
if (task.isSuccessful()) {
user_profile.getDownloadUrl().addOnSuccessListener(new OnSuccessListener < Uri > () {
#Override
public void onSuccess(Uri uri) {
//noinspection deprecation
String token_id = FirebaseInstanceId.getInstance().getToken();
Map < String, Object > userMap = new HashMap < > ();
userMap.put("id", userUid);
userMap.put("name", name_);
userMap.put("image", uri.toString());
userMap.put("email", email_);
userMap.put("bio", getString(R.string.default_bio));
userMap.put("username", username_);
userMap.put("location", location_);
userMap.put("token_id", "");
verification of email
#Override
public void onSuccess(Void aVoid) {
mDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Verification email sent", Toast.LENGTH_SHORT).show();
finish();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
mDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
mDialog.dismiss();
}
});
} else {
mDialog.dismiss();
}
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
task.getResult().getUser().delete();
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e("Error", e.getMessage());
}
});
} else {
mDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Error: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}

To solve this, please use the folloing lines of code:
service cloud.firestore {
match /databases/{database}/documents {
match /Users/{userId} {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}
}
}
Which basically means you can create user document if request.auth.uid != null and you can read, update, delete only if request.auth.uid == userId.
Edit:
You are getting that PERMISSION_DENIED warning because before trying to write to:
firebaseFirestore.collection("Users").document(userUid).set(userMap)
You are also trying to write data to:
firebaseFirestore.collection("Usernames").document(username_).set(usernameMap)
Where you have no permission. Please add the corresponding permissions to the first write operation and everything will be fine.

Related

implementing addOnProgressListener In Firebase

In my code i want to add OnProgressListener, but can't work. It gives me a syntax error.
Cannot resolve method 'addOnProgressListener' in 'Task'
How i can do this?
Please rewrite the code for me.
I Want to show progress dialog percentage.
For example: "uploading video 98%"
private void uploadImage_10() {
final ProgressDialog pd = new ProgressDialog(this);
pd.setMessage("Posting....");
pd.show();
if (video_url != null) {
final StorageReference fileReference = storageRef.child(System.currentTimeMillis()
+ "." + getFileExtension(video_url));
uploadTask = fileReference.putFile(video_url);
String desc = description.getText().toString();
if (desc.length() < 20) {
description.setError("Please Insert Document to long");
if (TextUtils.isEmpty(desc)) {
description.setError("Please insert Description");
Toast.makeText(this, "Please Insert Description", Toast.LENGTH_SHORT).show();
}
pd.dismiss();
} else {
uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
miUrlOk = downloadUri.toString();
DatabaseReference reference = FirebaseDatabase.getInstance("https://pineka-social-media-mast-da52a-default-rtdb.firebaseio.com/"
).getReference("Posts_video");
String postid = reference.push().getKey();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("postid", postid);
hashMap.put("time_post", ServerValue.TIMESTAMP);
hashMap.put("postvideo", miUrlOk);
hashMap.put("description", description.getText().toString());
hashMap.put("category", category.getSelectedItem().toString());
hashMap.put("publisher", FirebaseAuth.getInstance().getCurrentUser().getUid());
reference.child(postid).setValue(hashMap);
pd.dismiss();
startActivity(new Intent(PostActivityvideo.this, MainActivity.class));
finish();
} else {
Toast.makeText(PostActivityvideo.this, "Failed", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(PostActivityvideo.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
progressDialog.setMessage((int) progress + "");
}
});
}
} else {
Toast.makeText(PostActivityvideo.this, "No image selected", Toast.LENGTH_SHORT).show();
}
}
From what I can see you may have defined uploadTask as a Task.
To be able to call addOnProgressListener ,you'll want to declare it as an UploadTask.

realtime Database in firebase doesn't save data

realtime Database in firebase doesn't save data and doesn't show any errors
i have already set
"rules": {
".read": "true",
".write": "true"
}
and this is the function it create new user and it's created in firebase but the user name and email doesn't save in realtime database
public void createUser(String email, String password, String userName) {
auth = FirebaseAuth.getInstance();
auth.createUserWithEmailAndPassword(email, password).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(getContext(), "user created", Toast.LENGTH_SHORT).show();
User user = new User(email, userName);
FirebaseDatabase.getInstance().getReference().child("Users")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(getContext(), "user info added", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
and this line is appere as toast i don't know how it is happen
Toast.makeText(getContext(), "user info added", Toast.LENGTH_SHORT).show()

Why are no documents being returned?

I have this error when attempting to write to Firestore Database and I am at a loss. This is happening because documentReference.getDocuments() is empty but I expect it to be non-empty.
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.uni.strengthprogression.data.FirebaseManager$9.onSuccess(FirebaseManager.java:120)
at com.uni.strengthprogression.data.FirebaseManager$9.onSuccess(FirebaseManager.java:117)
Line 117:
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
Line 120:
String id = documentReference.getDocuments().get(0).getId();
Full method:
public static void addBenchSession(String userEmail, Session session, BackGroundTaskOperation backGroundTaskOperation) {
db.collection("users").whereEqualTo("email", userEmail).get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentReference) {
String id = documentReference.getDocuments().get(0).getId();
db.collection("users")
.document(id)
.update("bench_sessions", FieldValue.arrayUnion(session.toMap()))
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "Successfully added document");
backGroundTaskOperation.onSuccess(null);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error adding document", e);
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error adding document", e);
}
});
}
Andreas and Alex were correct... userEmail was null as I hadn't correctly utilized putExtra() and getExtra().

Applications stops its work when TextView is empty. How can I fix it?

I have a loginActivity class. that does email and password validation and checks if a login field is empty.
the problem is that my application stops if the login fields are empty.
Here's my code :
Validators :
private boolean validatePassword() {
boolean password1 = password.getText().toString().trim().isEmpty();
String password2 = password.getText().toString().trim();
if (password1) {
password.setError("Поле не должно быть пустым");
return false;
} else if (!PASSWORD_PATTERN.matcher(password2).matches()) {
password.setError("Слабый пароль. ");
return false;
} else {
password.setError(null);
return true;
}
}
private boolean validateEmail() {
String email1 = email.getText().toString().trim();
if (email1.isEmpty()) {
email.setError("Поле не должно быть пустым");
return false;
} else if (!Patterns.EMAIL_ADDRESS.matcher(email1).matches()) {
email.setError("Введите правильный E-mail");
return false;
} else {
email.setError(null);
return true;
}
}
Registeration :
public void register(final String email, final String password) {
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (validateEmail() & validatePassword()) {
if (task.isSuccessful()) {
Toast.makeText(LogInActivity.this, "Successfully", Toast.LENGTH_SHORT).show();
} else Toast.makeText(LogInActivity.this, "Failed", Toast.LENGTH_SHORT).show();
} else if (email.isEmpty() || password.isEmpty())
Toast.makeText(LogInActivity.this, "Поля не должно быть пустыми", Toast.LENGTH_SHORT).show();
}
});
}
Login :
public void logIn(final String email, final String password) {
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (checkBox.isChecked()) {
if (validateEmail()) {
if (task.isSuccessful()) {
Toast.makeText(LogInActivity.this, "Successfully", Toast.LENGTH_SHORT).show();
startNewActivity();
} else
Toast.makeText(LogInActivity.this, "Failed", Toast.LENGTH_SHORT).show();
} else if (email.isEmpty() || password.isEmpty())
Toast.makeText(LogInActivity.this, "Проверьте введенные данные", Toast.LENGTH_SHORT).show();
;
}
}
});
}
Changing activity :
private void startNewActivity() {
Intent intent = new Intent(context, MainActivity.class);
startActivity(intent);
this.finish();
}
I am unable to find an error in your code because you didn't post any logcat error message but I worked on something similar and it works perfectly for me, just change my fields like editTextPassword, editTextEmail and also in intents with your fields and you are good too go.
private void userLogin() {
String email = editTextEmail.getText().toString().trim();
String password = editTextPassword.getText().toString().trim();
if (email.isEmpty()) {
editTextEmail.setError("Email is required");
editTextEmail.requestFocus();
return;
}
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
editTextEmail.setError("Please enter a valid email");
editTextEmail.requestFocus();
return;
}
if (password.isEmpty()) {
editTextPassword.setError("Password is required");
editTextPassword.requestFocus();
return;
}
if (password.length() < 6) {
editTextPassword.setError("Minimum lenght of password should be 6");
editTextPassword.requestFocus();
return;
}
progressBar.setVisibility(View.VISIBLE);
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
progressBar.setVisibility(View.GONE);
if (task.isSuccessful()) {
finish();
Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
you just have to call this function when the user clicks on login button.
Button loginButton = (Button)findViewById(R.id.buttonLogin);
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
userLogin();
}
});

I want to retrieve videos from firebase storage

I am working on simple firebase app in which I upload user info as registration data and uploading videos in storage. Path of videos is also stored in realtime database as nested child of every particular user which is working properly, but I don't know how to retrieve video and set in user profile with other user information. I need code to retrieve video from storage.
case PICK_VIDEO_REQUEST:
if (resultCode == RESULT_OK) {
selectedVideoUri = data.getData();
userUid = FirebaseAuth.getInstance().getCurrentUser().getEmail();
StorageReference storageRef = FirebaseStorage.getInstance().getReference();
filename = data.getData().getLastPathSegment();
tv_file_path.setText(filename);
videoRef = storageRef.child("/videos/" + userUid + "/" + filename);
//TODO: save the video in the db
}
break;
`//Button upload data in firebase
btn_upload_notes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
uploadData(selectedVideoUri);
try {
if (FirebaseAuth.getInstance().getCurrentUser().getEmail().equals(value.getT_email())) {
file_name = filename;
notes_Category = text;
lecture_topic = et_topic.getText().toString().trim();
id = mDatabase.push().getKey();
NotesModelClass notesModelClass = new NotesModelClass(id, notes_Category, lecture_topic, file_name);
mDatabase.child(value.getT_id()).child("Video Notes").child(id).setValue(notesModelClass);
return;
}
}
catch (Exception ex){
throw ex;
}
}
});
`
private void uploadData(Uri videoUri) {
if (videoUri != null) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
UploadTask uploadTask = videoRef.putFile(videoUri);
uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful())
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Upload Complete", Toast.LENGTH_SHORT).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot
.getTotalByteCount());
progressDialog.setMessage("Uploaded " + (int) progress + "%");
}
});
} else {
Toast.makeText(MainActivity.this, "Nothing to upload", Toast.LENGTH_SHORT).show();
}
}
Try this code
Retrive single video.
StorageReference videoRef = storageRef.child("/videos/" + userUid + "/" + filename);
final long ONE_MEGABYTE = 1024 * 1024;
videoRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
// Transform bytes to a video, play
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
Retrieve multiple video
StorageTask<UploadTask.TakeSnapshot> storageTask;
storageTask = yourStorageRefernce.putFile(videoUri);
storageTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
return yourStorageRefernce.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
arrayList.add(downloadUri.toString());
}
}
});
Help me random video in firebase
private void loadVideosFromFirebase() {
videoArrayList=new ArrayList<>();
DatabaseReference reb = FirebaseDatabase.getInstance().getReference().child("Videos");
reb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds:dataSnapshot.getChildren()) {
ModelVideo modelVideo = ds.getValue(ModelVideo.class);
videoArrayList.add(modelVideo);
}
adapterVideo = new AdapterVideo(VideosActivity.this,videoArrayList);
videosRv.setAdapter(adapterVideo);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}

Categories