Is there any way to print errors in Firebase? - firebase

Is it possible to print error on firebase? not create another collection and create document
Example: I called cloud function. but when cloud function failed we can't find which error/error code. Now, I debug application and run cloud function again check with my console. Is there any way to print in firebase?
if (result.data['success']) {
finalize();
} else if (result.data['errorCode'] == 1003) {
print(result.data['errorMessage']);
} else {
print(result.data['errorMessage']);
}
} on CloudFunctionsException catch (e) {
print(e);
} catch (e) {
print(e);
}
And also other errors. api call errors etc

Every error produced by function is stored in Firebase Dashboard -> Function -> Logs (tab). Moreover, when you create your own function, every console.log() is logged there.

Related

Kotlin firebase executed with addOnSuccessListener even if fails

I have this piece of code and it is executed with .continueWith and addOnSuccessListener even if failed.I try with continueWithTask but i dont understand very well Tasks API. Please help me to understand how to do this.
db.collection(customGameName).document().get().continueWith {
if (!gameslist.contains(customGameName)) {
gameslist.add(customGameName)
SavedPreference.setGamesList(this, gameslist)
adapter.notifyDataSetChanged()
}else{
Toast.makeText(this,"$customGameName is in the list already!",Toast.LENGTH_SHORT).show()
}
}.addOnFailureListener {
Toast.makeText(this,"$customGameName not exist!",Toast.LENGTH_SHORT).show()
gameslist.remove(customGameName)
SavedPreference.setGamesList(this, gameslist)
adapter.notifyDataSetChanged()
}
If you have code that you only want to run when the task is successful, add a success listener to the task. That should look something like this:
db.collection(customGameName).document().get()
.addOnSuccessListener { document ->
if (document != null) {
Log.d(TAG, "DocumentSnapshot data: ${document.data}")
if (!gameslist.contains(customGameName)) {
gameslist.add(customGameName)
SavedPreference.setGamesList(this, gameslist)
adapter.notifyDataSetChanged()
}else{
Toast.makeText(this,"$customGameName is in the list already!",Toast.LENGTH_SHORT).show()
}
} else {
Log.d(TAG, "No such document")
}
}.addOnFailureListener {
Toast.makeText(this,"$customGameName not exist!",Toast.LENGTH_SHORT).show()
gameslist.remove(customGameName)
SavedPreference.setGamesList(this, gameslist)
adapter.notifyDataSetChanged()
}
Note that this code is pretty much straight from the Firebase documentation on getting a document in Kotlin, so I recommend spending some more time there.

How to catch all different kind of errors from Firebase Storage in Flutter?

I would like to be able to catch and respond according to specific errors from firebase_storage in my Flutter app.
Here is what i would like to do:
UploadTask task = FirebaseStorage.instance.reference().putFile("filePath");
task.catchError((FirebaseStorageException exception) {
switch (exception.state) {
case FirebaseStorageExceptionState.unknown:
break;
case FirebaseStorageExceptionState.canceled:
break;
...
}
})
For now I'm doing the catch this way according to the documentation:
task.catchError((FirebaseException error) {
if (error.code == "canceled") {
...
}
})
Which is definitely not a good way to go because i don't know all of the String and they may changed in the future...
Is there any way to be able to do this?

How can I use .updateData() instead of .setData() in flutter firestore even when document does not exist

I am trying to do something along the lines that, if there does not exist a document then do setData and if the document exist, do update data... I have tried this(the code below), it seems to work but I am concerned that what if when I launch the app and the error message changes.
Future updateReference(
String phoneNumber,
) async {
try {
return await mCollectionRef.document(phoneNumber).updateData({
uid: true,
});
} on PlatformException catch (error) {
print(error.message.substring(0, 9));
if (error.message.substring(0, 9) == 'NOT_FOUND') {
return await mCollectionRef.document(phoneNumber).setData({
uid: true,
});
}
}
}
Is there any other way in which I can achieve this?
If you want to update or create a document if it doesn't already exist, you can just pass merge: true as the second argument to setData().

How to Use Firebase with Nativescript-Vue?

I've been trying to implement just a simple Firebase fetch since November. At this point, I wish I'd just created a new Rails api; it would have been faster.
But everyone insists Firebase is Oh So Simple.
In app.js,
import firebase from 'nativescript-plugin-firebase';
That part seems OK.
Instructions are all over the place after that.
The plugin's ReadMe suggests an initialization:
firebase.init({
// Optionally pass in properties for database, authentication and cloud messaging,
// see their respective docs.
}).then(
function () {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
Several others have insisted that the init code is unnecessary. It does run without errors, but the code he gives after that produces nothing. Also,
const db = firebase.firestore;
const UserStatusCollection = db.collection("UserStatus");
UserStatusCollection.get();
produce an empty object {}.
Here's my Firebase collection:
If I wrap the firebase call in async/await (and no one is showing it as this complicated),
async function getFireStoreData() {
try {
let result = await this.UserStatusCollection.get();
console.log(result);
return result;
}
catch (error) {
console.error(
"UserStatusCollection.get()" + error
);
}
}
And call that
let temp2 = getFireStoreData();
console.log("temp2:" + temp2);
All I ever get is an object promise.
As I said, I wish I had just built up a new Rails API and had a far simpler life since November.
Your getFireStoreData method is asynchronous and you're not awaiting it. That is probably the reason why you're getting a promise back. Try to await getFireStoreData(). See if that works.
Since it's also a promise, you can try to use .then.
getFireStoreData().then(data => {
console.log(data);
})

How to force logout firebase auth user from app remotely

I have a project which uses firebase auth with firebaseUI to authenticate users. I have enabled Google, Facebook and email providers. What I need is to remotely logout or disable some of the users.
I want the users to logout from the app on doing so. I tried disabling the user in the firebase console and also used the firebase admin SDK (https://firebase.google.com/docs/auth/admin/manage-sessions) to revoke the refresh tokens.
I waited for more than 2 days and still noticed that the user was logged in and could access the firestore data.
I have also gone through and tried
Firebase still retrieving authData after deletion
Can anyone point to what I am doing wrong ?
You also cannot remotely force a user to be signed out. Any sign out will have to happen from the device that the user is signed in on.
There is no way to revoke an access token once that is minted. This means that even if you disable the user's account, they may continue to have access for up to an hour.
If that is too long, the trick (as also mentioned in my answer to the question you linked) is to maintain a list of blocked users in your database (or elsewhere) and then check against that in your security rules (or other authorization layer).
For example in the realtime database, you could create a list of blocked user's UIDs:
banned_uids: {
"uid1": true
"uid2": true
}
And then check against that in your security rules with:
".read": "auth.uid !== null && !root.child('banned_uids').child(auth.uid).exists()"
You can send a message data with FCM to force to log out.
For example, if the users use android application.
Save the FCM token in a collection in firebase Realtime.
configure the Android client app, in the service. LINK You have to make when receive a message with especial string, force to log out.
make the trigger you need in cloud functions, to send the data LINK when you need the user log out.
SUCCESS!
As per your scenarios, i assume that you need to make user logout when user is disabled.
Use One global variable to store TokenNo (might be in shared preference or sqlite):
Add following code to your manifest:
<service android:name=".YourFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Add following code in your
public class LogoutOntokenchange extends FirebaseMessagingService{
#Override
public void onNewToken (String token){
if(TokenNo=>1){ //if tokenNo >=1 means he already logged in
TokenNo=0;
FirebaseAuth.getInstance().signOut(); //Then call signout method
}
else{
TokenNo=1; //store token no in db
}
}
}
What Happens here:
When user logged in first time onNewToken is called then It goes into else then TokenNo is updated to 1 from 0.
When You disable any user then automatically token is refreshed.Then OnNewToken is called then TokenNo>=1 so user will be logged out.
NOTE: When user log in for first time i.e if TokenNo variable is not stored then store it as 0.
For reference: https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/FirebaseMessagingService
The only way I can think about is adding a if-else block in your starting activity.
Store the that status of user (verified/banned/deleted) in Firebase Real-time database. Then retrieve the status of user at start of application and add the code:
if (currentUserStatus.equals("banned"))
{
currentUser.logout();
}
What I've done is I created for each user upon registration a Firestore document with the UID as document ID. In this document I store an array which stores all fcm tokens the individual user receives when logging into a new device. That way I always keep track where the user is logged in. When the user logs out manually the fcm token will be deleted from the document in Firestore as well as on the device.
In order to be able to log out the user everywhere they are signed in I did the following. When starting the app and once the user is logged in I start a snapshot listener that listens to all changes in the users document. As soon as there is a change I retrieve the new array of fcm tokens, search inside the array for the local current device fcm token. If found, I do nothing. If the fcm token is no longer in the array I will call the local logout method and go back to the login screen.
Here are the methods I used in swift on iOS. The closures (passOnMethod) will just trigger an unwind segue to the login view controller.
import Foundation
import Firebase
class FB_Auth_Methods {
let db = Firestore.firestore()
var listener: ListenerRegistration?
func trackLoginStatus(passOnMethod: #escaping () -> () ) {
listener?.remove()
if let loggedInUserA_UID = Auth.auth().currentUser?.uid {
listener = db.collection(K.FStore.collectionOf_RegisteredUsers_Name)
.document(loggedInUserA_UID)
.addSnapshotListener { (snapshotDocument, error) in
if let error = error {
print(error)
} else {
if let document = snapshotDocument {
if let data = document.data() {
if let fcmTokens = data[K.FStore.Users.fcmTokens] as? [String] {
print("Found the following tokens: \(fcmTokens)")
self.compareTokensAgainstCurrentDeviceToken(fcmTokens: fcmTokens, passOnMethod: { () in
passOnMethod()
})
}
}
}
}
}
}
}
func compareTokensAgainstCurrentDeviceToken(fcmTokens: [String], passOnMethod: #escaping () -> () ) {
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print(error)
} else if let result = result {
if fcmTokens.contains(result.token) {
print("Token found, doing nothing")
} else {
print("Token no longer found, logout user")
do {
try Auth.auth().signOut()
InstanceID.instanceID().deleteID { error in
if let error = error {
print(error)
} else {
passOnMethod()
}
}
} catch let signOutError as NSError {
print (signOutError)
}
}
}
}
}
}
And here is the method I use when logging out the user everywhere but at the current device.
func deleteAllFcmTokensExceptCurrent(loggedInUserA: User, passOnMethod: #escaping () -> () ) {
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print(error)
} else if let result = result {
let batch = self.db.batch()
let deleteAllFcmRef = self.db.collection(K.FStore.collectionOf_RegisteredUsers_Name).document(loggedInUserA.uid)
batch.updateData([K.FStore.Users.fcmTokens: FieldValue.delete()], forDocument: deleteAllFcmRef)
let updateFcmTokenRef = self.db.collection(K.FStore.collectionOf_RegisteredUsers_Name).document(loggedInUserA.uid)
batch.updateData([K.FStore.Users.fcmTokens: FieldValue.arrayUnion([result.token])], forDocument: updateFcmTokenRef)
batch.commit { (error) in
if let error = error {
print(error)
} else {
passOnMethod()
}
}
}
}
}
Not tested yet, as our backend programmer, who is in charge of setting up Firestore rules was gone for the day, but in theory this should work: (and it's something I'll test tomorrow)
Having a FirebaseAuth.AuthStateListener in charge of serving UI based on the status of the user
This combined with rules in firestore
match /collection
allow read: if isAuth();
Where isAuth is:
function isAuth() {
return request.auth.uid != null;
}
If the user is then disabled, while being logged in, whenever the user tries to read data from the collection, he should be denied, and a signOut() call should be made.
The AuthStateListener will then detect it, and sign the user out.

Resources