Я написал простую облачную функцию:
import * as functions from 'firebase-functions';
export const repeat = functions.https.onCall( function (data, context) {
// Authentication user information is automatically added to the request.
if (context.auth) {
console.log(' context.auth is defined ');
console.log(' uid is ' + context.auth.uid);
} else {
console.log(' context.auth undefine. ');
}
if (context.auth) {
return {
repeat_message: context.auth.uid + ' ' + data.message,
repeat_count: data.count + 1,
};
} else {
return {
repeat_message: ' noUID ' + data.message,
repeat_count: data.count + 1,
};
} }
);
И соответствующее приложение клиента Flutter:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:cloud_functions/cloud_functions.dart';
final FirebaseAuth _fAuth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email'], signInOption: SignInOption.standard);
FirebaseUser _firebaseUser;
GoogleSignInAccount _googleSignInAccount;
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
caption: TextStyle(
fontSize: 20.0
),
body1: TextStyle(
fontSize: 20.0
),
),
),
title: 'calling function',
debugShowCheckedModeBanner: false,
home: LaunchScreen(),
);
}
}
class LaunchScreen extends StatefulWidget {
@override
_LaunchScreenState createState() {
return _LaunchScreenState();
}
} // LoggingOptions to _LaunchScreenState
class _LaunchScreenState extends State<LaunchScreen> {
String _response = 'no response';
int _responseCount = 1;
final HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(functionName: 'repeat')
..timeout = const Duration(seconds: 90);
Future<FirebaseUser> _handleSignIn() async {
try {
GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn();
_googleSignInAccount = googleSignInAccount;
GoogleSignInAuthentication authentication = await googleSignInAccount.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: authentication.accessToken, idToken: authentication.idToken,
);
AuthResult authResult;
authResult = await _fAuth.signInWithCredential( credential);
_firebaseUser = authResult.user;
setState(() {});
return _firebaseUser;
} catch (e) {
print(e.toString());
}
return null;
}
Future<void> _handleSignOut() async {
FirebaseAuth.instance.signOut();
_googleSignIn.signOut();
setState(() {
_firebaseUser =null;
_googleSignInAccount= null;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar( title: const Text('Sample Code'),),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MaterialButton(
child: const Text( 'Sign in with Google', style: TextStyle(fontSize: 16.0),),
onPressed: () {
_handleSignIn().then((user) {
// logggedIn
debugPrint('user ' + user.toString());
}
);
},
),
MaterialButton(
child: const Text( 'Sign out with Google', style: TextStyle(fontSize: 16.0),),
onPressed: () {
_handleSignOut();
},
),
Text( _firebaseUser != null ? _firebaseUser.uid : 'user logged off'),
Text('FromServer $_responseCount: $_response'),
MaterialButton(
child: const Text('SEND REQUEST', style: TextStyle(fontSize: 18.0),),
onPressed: () async {
try {
final HttpsCallableResult result = await callable.call(
<String, dynamic>{
'message': 'hello',
'count': _responseCount,
}
,
);
print(result.data);
setState(() {
_response = result.data['repeat_message'];
_responseCount = result.data['repeat_count'];
});
} on CloudFunctionsException catch (e) {
print('caught Firebase functions exception');
print(e.code);
print(e.message);
print(e.details);
} catch (e) {
print('caught generic exception');
print(e);
}
},
),
],
),
));
} }
, и я могу видеть в обоих журналах сервера и на стороне клиента, что Auth
передается корректно.
Но когда я добавляю allAuthenticatedUsers
и удаляю allUsers
к роли 'Cloud Functions Invoker' из функции , приложение начинает получать PlatformException
с кодом UNAUTHENTICED.
Вот как выглядит настройка до изменения:
И после добавления allAuthenticatedUsers
:
После удаления allUsers
:
Затем при флаттере вызывает функцию (когда пользователь вошел в систему), Flutter ошибки с
PlatformException (functionsError, Cloud функция не выполнена с исключением., {message: UNAUTHENTICATED, подробности: ноль, код: UNAUTHENTICATED })
Ошибка должна отображаться только в том случае, если пользователь не вошел в систему, но она отображается в любом случае.