I am facing one issue in Displaying persmissions (like Access Current location, Access Contacts, Access Phone Calls) when we are opening the app.
The Current Scenario is " In Android, If we give "Allow" or "Deny", then only the next permission Popup will display.
But in IOS, The current existing Scenario is, all the permission Popup's will come at a time. So, I want to change that displaying Permissions like in Android.
I am using the following code for iOS in AppDelegate.cs:
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = this;
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) =>
{
Console.WriteLine(granted);
});
}
else
{
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
var cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
await CrossPermissions.Current.RequestPermissionsAsync(Permission.Camera);
cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
if (cameraStatus != PermissionStatus.Granted)
{
}
var locationStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
locationStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (locationStatus != PermissionStatus.Granted)
{
}
Anyone Please help me out from this issue.
Thanks!
i code like below and it works:
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = this;
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) =>
{
Console.WriteLine(granted);
AcessPermissionsAsync();
});
}
else
{
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
private async System.Threading.Tasks.Task AcessPermissionsAsync()
{
try
{
//await GetPermissions();
var cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
await CrossPermissions.Current.RequestPermissionsAsync(Permission.Camera);
cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
if (cameraStatus != PermissionStatus.Granted)
{
var locationStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
locationStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (locationStatus != PermissionStatus.Granted)
{
}
}
else
{
var locationStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
locationStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (locationStatus != PermissionStatus.Granted)
{
}
}
}
catch(Exception ex)
{
}
}
Related
How to add Flutter Firebase VIdeo Upload Progrese Indecator | Upload Progress Indicator |
Anyone can help me
MediaInfo compressVideo = await VideoCompress.compressVideo(
videoPath,
quality: VideoQuality.Res640x480Quality,
includeAudio: true,
);
print('video Compressing Done');
var uploadVideo = await FirebaseStorage.instance
.ref()
.child("videos/${Me.get().uid}/${videoDoc.id}")
.putFile(File(compressVideo?.path));
print('video Uploading Done');
final videoUrl = await uploadVideo.ref.getDownloadURL();
showToast("Upload Successful");
This should be a good example from it:
Future<void> handleTaskExample2(String filePath) async {
File largeFile = File(filePath);
firebase_storage.UploadTask task = firebase_storage.FirebaseStorage.instance
.ref("videos/${Me.get().uid}/${videoDoc.id}")
.putFile(File(compressVideo?.path));
task.snapshotEvents.listen((firebase_storage.TaskSnapshot snapshot) {
print('Task state: ${snapshot.state}');
print(
'Progress: ${(snapshot.bytesTransferred / snapshot.totalBytes) * 100} %');
}, onError: (e) {
// The final snapshot is also available on the task via `.snapshot`,
// this can include 2 additional states, `TaskState.error` & `TaskState.canceled`
print(task.snapshot);
if (e.code == 'permission-denied') {
print('User does not have permission to upload to this reference.');
}
});
// We can still optionally use the Future alongside the stream.
try {
await task;
print('Upload complete.');
} on firebase_core.FirebaseException catch (e) {
if (e.code == 'permission-denied') {
print('User does not have permission to upload to this reference.');
}
// ...
}
}
I would also recommend to check the docs for more details.
finally, I'm getting the right answer.
This answer is perfectly works in my case.
//This is the document reference
Reference videoRef = FirebaseStorage.instance
.ref()
.child("videos/${Me.get().uid}/${videoDoc.id}");
//Here video is uploading and return UploadTask
UploadTask videoTask = videoRef.putFile(compressVideo.file);
//This is upload task StreamSubscription
final StreamSubscription<void> streamSubscription =
videoTask.snapshotEvents.listen((data) {
double uploadPer;
setState(() => uploadPer = (data.bytesTransferred / data.totalBytes)*
100);
print(uploadPer);
});
//When video uploading is completed then streamSubscription is cancel.
await videoTask.whenComplete(() => null);
streamSubscription.cancel();
//This is finally get video download URL
final String videoUrl = await videoRef.getDownloadURL();
print(videoUrl);
showToast("Upload Successful");
I have an web application written in .Net Core both Backend + Frontend
I have login page with Email + Password + Remember Me ( Checkbox )
I want if user click on remember me stay signed in forever until he/she clear cookies.
When user logging in I save ACCESS_TOKEN + REFRESH_TOKEN in Principals Here is example of Login Method:
public async Task<IActionResult> LoginAsync(LoginViewModel loginViewModel)
{
if (ModelState.IsValid)
{
var requestDto = _mapper.Map<LoginRequestDto>(loginViewModel);
try
{
var response = await _authenticationClient.LoginAsync(requestDto);
var claimsIdentity = new ClaimsIdentity(new[]
{
new Claim(CustomUserClaimTypes.AccessToken, response.AccessToken),
new Claim(CustomUserClaimTypes.RefreshToken, response.RefreshToken),
new Claim(CustomUserClaimTypes.FullName, response.Fullname),
new Claim(CustomUserClaimTypes.UserName, response.Username),
new Claim(CustomUserClaimTypes.UserId, response.UserId),
new Claim(CustomUserClaimTypes.Email, response.Email),
new Claim(CustomUserClaimTypes.TokenExpireTime, response.TokenExpire.ToString())
}, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(scheme: CookieAuthenticationDefaults.AuthenticationScheme);
var principals = new ClaimsPrincipal(claimsIdentity);
if (loginViewModel.IsPersistent)
{
await HttpContext.SignInAsync(scheme: CookieAuthenticationDefaults.AuthenticationScheme, principals, new AuthenticationProperties
{
IsPersistent = true,
AllowRefresh = true,
IssuedUtc = DateTime.Now
});
}
else
{
await HttpContext.SignInAsync(scheme: CookieAuthenticationDefaults.AuthenticationScheme, principals, new AuthenticationProperties { IsPersistent = false, AllowRefresh = true });
}
return new JsonResult(new
{
success = true,
result = "/home"
});
}
catch (ApiException ex)
{
if (ex.ErrorResponse != null)
{
return new JsonResult(new
{
success = false,
result = ex.ErrorResponse.Errors.Select(x => x.Message)
});
}
if (ex.Response != null)
{
return new JsonResult(new
{
success = false,
result = ex.Response
});
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
return View("Index");
}
Token Expire Time is 5 Minutes, I want if user clicked remember me after this 5 minutes I need to refresh token to make sure access token is valid
Here is example of Refresh Token :
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/Authentication/Index";
options.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = async x =>
{
var identity = (ClaimsIdentity)x.Principal.Identity;
var tokenExpire = identity.FindFirst(CustomUserClaimTypes.TokenExpireTime);
if (DateTime.Parse(tokenExpire.Value) < DateTime.Now)
{
var accessTokenClaim = identity.FindFirst(CustomUserClaimTypes.AccessToken);
var refreshTokenClaim = identity.FindFirst(CustomUserClaimTypes.RefreshToken);
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://test.api.com/api/v1/");
var requestData = new RefreshTokenRequestApiDto
{
AccessToken = accessTokenClaim.Value,
RefreshToken = refreshTokenClaim.Value
};
var jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(requestData);
var stringContent = new StringContent(jsonData, Encoding.UTF8, "application/json");
var result = await client.PostAsync("auth/refresh-token", stringContent);
if (result.IsSuccessStatusCode)
{
var deserializedData = await result.Content.ReadAsStringAsync();
var mapped = Newtonsoft.Json.JsonConvert.DeserializeObject<BaseApiResponse<BaseAuthenticationResponseDto>>(deserializedData);
if (mapped != null)
{
identity.RemoveClaim(accessTokenClaim);
identity.RemoveClaim(refreshTokenClaim);
identity.RemoveClaim(tokenExpire);
identity.AddClaims(new[]
{
new Claim(CustomUserClaimTypes.AccessToken, mapped.Result.AccessToken),
new Claim(CustomUserClaimTypes.RefreshToken, mapped.Result.RefreshToken),
new Claim(CustomUserClaimTypes.TokenExpireTime, mapped.Result.TokenExpire.ToString())
});
x.ShouldRenew = true;
}
}
}
}
}
};
});
The problem is when I try on localhost everything working good, User is persist, even I turn off my PC, But when I publish this to my PLESK panel, and Try it from there, after 5 minutes user signed out and on cookie the AspNet.Cookies is exist but user seems unauthorized, I need to login again after 5 minutes continuously.
Anything wrong on my code ?
Or I need to do something on my Plesk Panel ?
SORRY ABOUT MY ENGLISH :)
Thanks!
I stuck at this error for a month I cannot find any solution via google.
I build a chat app which need to work both online and offline, backend is NodeJS
Below code is send any message that still in pending to target devices
async function _worker(socket) {
console.log('worker running...')
await connect.then(async (db) => {
// When user A sent message to user B but user B is offline so server need to sync this message to user B
Message.find({ isDeliver: 0 }).then(async (m) => {
if (m.length > 0) {
for (let i = 0; i < m.length; i++) {
let sender = m[i].sender;
let receiver = m[i].receiver;
let online = await checkUserOnline(socket, receiver);
if (online) {
let to_user_socket_id = getSocketIDfromMapForthisUser(`${receiver}`)
sendToConnectedSocket(socket, to_user_socket_id, "send_message_to_device", m[i]);
}
}
}
});
// When user A sent a message to user B and user B is offline but when user B is online and message delivered to user B and user A is offline server need to sync this message status to update for user A
Message.find({ isDeliver: 1 }).then(async (m) => {
if (m.length > 0) {
for (let i = 0; i < m.length; i++) {
let sender = m[i].sender;
let receiver = m[i].receiver;
let online = await checkUserOnline(socket, sender);
if (online) {
let to_user_socket_id = getSocketIDfromMapForthisUser(`${sender}`)
sendToConnectedSocket(socket, to_user_socket_id, "send_message_deliver", m[i]);
}
}
}
});
// When user A sent a message to user B and user B is offline but when user B is online and read the message and user A is offline server need to sync this message status to update for user A
Message.find({ isRead: 1 }).then(async (m) => {
if (m.length > 0) {
for (let i = 0; i < m.length; i++) {
let sender = m[i].sender;
let receiver = m[i].receiver;
let online = await checkUserOnline(socket, sender);
if (online) {
let to_user_socket_id = getSocketIDfromMapForthisUser(`${sender}`)
sendToConnectedSocket(socket, to_user_socket_id, "send_message_read", m[i]);
}
}
}
});
});
}
and below is a method to handle event from server:
Socket
setOnServerSendDeliver(Function onServerSendDeliver) {
_socket.on('send_message_deliver', (data) {
onServerSendDeliver(data);
});
}
setOnServerSendRead(Function onServerSendRead) {
_socket.on('send_message_read', (data) {
onServerSendRead(data);
});
}
setOnServerSendToDevice(Function onServerSendToDevice) {
_socket.on('send_message_to_device', (data) {
onServerSendToDevice(data);
});
}
Method
onServerSendDeliver(data) async {
MessageModel message = MessageModel.fromJson(jsonDecode(data));
await G.dbService.updateDeliver(message);
G.socketUtils.sendDeliveryDone(message, new UserModel(id: message.sender));
refreshMessage();
}
onServerSendRead(data) async {
MessageModel message = MessageModel.fromJson(jsonDecode(data));
await G.dbService.updateRead(message.chatId);
G.socketUtils.sendReadDone(message, new UserModel(id: message.sender));
refreshMessage();
}
onServerSendToDevice(data) async {
MessageModel message = MessageModel.fromJson(jsonDecode(data));
ChatModel chat = new ChatModel();
chat.id = message.chatId;
chat.fromId = message.sender;
chat.toId = message.receiver;
chat.message = message.content;
await G.dbService.chatOperation(chat);
await G.dbService.insertMessage(message);
await G.dbService.updateDeliver(message);
G.socketUtils.sendDelivery(message, new UserModel(id: message.sender));
refreshMessage();
}
in server I set
setInterval(_worker, 1500, socket);
to load check message and send to end devices
and my database function
Future<String> updateRead(String chatId) async {
Database db = await database;
try {
await db.transaction((txn) async {
return await txn.rawUpdate(
"UPDATE messages SET isRead = 1, isSend = 1, isDeliver = 1 WHERE chatId = ? AND status = 0",
[chatId]);
});
await db.transaction((txn) async {
return await txn.rawUpdate(
"UPDATE chats SET isRead = 1, isSend = 1, isDeliver = 1 WHERE id = ? AND status = 0",
[chatId]);
});
} catch (e) {
print(e.toString());
}
return chatId;
}
Future<String> updateDeliver(MessageModel message) async {
Database db = await database;
String id;
try {
id = message.id;
await db.transaction((txn) async {
return await txn.rawUpdate(
"UPDATE messages SET isDeliver = 1 WHERE id = ? AND status = 0",
[message.id]);
});
await db.transaction((txn) async {
return await txn.rawUpdate(
"UPDATE chats SET isDeliver = 1 WHERE id = ? AND status = 0",
[message.chatId]);
});
} catch (e) {
print(e.toString());
}
return id;
}
iOS is working fine but on android I always got this error and my app stuck:
flutter: Warning database has been locked for 0:00:10.000000. Make sure you always use the transaction object for database operations during a transaction
Any help would be appropriate
Update
I tried to modify the database function to:
Future<String> updateDeliver(MessageModel message) async {
Database db = await database;
String id;
try {
id = message.id;
await db.transaction((txn) async {
var batch = txn.batch();
batch.rawUpdate(
"UPDATE messages SET isDeliver = 1 WHERE id = ? AND status = 0",
[message.id]);
batch.rawUpdate(
"UPDATE chats SET isDeliver = 1 WHERE id = ? AND status = 0",
[message.chatId]);
batch.commit();
});
} catch (e) {
print(e.toString());
}
return id;
}
but I still faced the same issue
Make sure to await any async method in a transaction:
await batch.commit();
You should use pedantic (or the proper lints) to get a warning when you forget such await.
And yes, don't create a transaction for a single operation and try to group actions in transaction (and batches if you can).
You could also turn on logging to make sure you are not doing too many sqlite queries.
now , i'm trying to take a photo with a button and i'll send it to database without saving it to gallery ,My constraint is that user can't take a photo from gallery it should be a real time , so how can i do this ?
use the Media plugin
takePhoto.Clicked += async (sender, args) =>
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
DisplayAlert("No Camera", ":( No camera available.", "OK");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "Sample",
Name = "test.jpg"
});
if (file == null)
return;
await DisplayAlert("File Location", file.Path, "OK");
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
return stream;
});
};
I'm trying to avoid using the .then((u) { return u.uid }) function in all my code where I need to access the current user's UID, instead just by calling getCurrentUser().uid for a much faster access. However, it gives me an error The getter 'uid' was called on null. but it's not null because it does print in the console but only after showing that it's null and the error at the end for some reason. I'm not well knowledge in the Future/Async/Await logic so any help would be greatly appreciated!
class UsersAPI {
final DatabaseReference usersRef = FirebaseDatabase.instance.reference().child(Config.users);
Future<FirebaseUser> currentUser() async {
return await FirebaseAuth.instance.currentUser();
}
FirebaseUser getCurrentUser() {
FirebaseUser user;
this.currentUser().then((u) {
user = u;
print('USER 1 $user'); // Prints after 'USER 2'
});
print('USER 2 $user'); // Prints first
if (user != null) {
return user;
} else {
return null;
}
}
DatabaseReference getCurrentUserRef() {
return this.usersRef.child(this.getCurrentUser().uid); // GIVES THE 'uid' WAS CALLED ON NULL ERROR
}
observeCurrentUser(Function onSuccess(User u)) {
this.usersRef.child(this.getCurrentUser().uid).onValue.listen( (event) { // GIVES THE 'uid' WAS CALLED ON NULL ERROR
DataSnapshot snapshot = event.snapshot;
if (snapshot.value != null) {
User user = User().transform(snapshot.key, snapshot.value);
onSuccess(user);
}
});
}
observeUser(String userID, Function onSuccess(User u), Function onFailure(String e)) {
this.usersRef.child(userID).onValue.listen( (e) {
DataSnapshot snapshot = e.snapshot;
if (snapshot.value != null) {
User user = User().transform(snapshot.key, snapshot.value);
onSuccess(user);
} else {
onFailure("User Not Found...");
}
});
}
}
Example Usage - WORKS:
APIs().usersAPI.currentUser().then((u) {
APIs().usersAPI.observeUser(u.uid, (u) {
onSuccess(u);
}, (e) {
print(e);
});
});
DOESN'T WORK:
APIs().usersAPI.observeCurrentUser((u) {
onSuccess(u);
});
DatabaseReference getCurrentUserRef() async {
return this.usersRef.child((await this.getCurrentUser()).uid); =
}
than call
var ref = await getCurrentUserRef()
Little bit more pretty
DatabaseReference getCurrentUserRef() async {
var firebaseUser = await this.getCurrentUser();
return this.usersRef.child(firebaseUser.uid);
}
EDIT: to clarify some question on asynchronicity
How would you call now this function to get the reference?
Lets say you want to update the data on the user, you can do
Firestore.instance.runTransaction((transaction) async {
var reference = await getCurrentUserRef();
await transaction.set(reference, someData);
});
Or you would like to read the data from that reference
readAndProcessData() async {
var reference = await getCurrentUserRef();
DocumentSnapshot user = await reference.get();
print(user.data.toString);
}