Любой пакет Flutter, который получает токен доступа GoogleCredential
Во Flutter(Dart) есть какой-нибудь пакет для получения GoogleCredential Accesstoken (этот пример ниже для получения Access Token в Java)
private static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream("service-account.json"))
.createScoped(Arrays.asList(SCOPES));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}
Мне нужно, чтобы изменить Firebase удаленного конфигурации.
2 ответа
Если вы ищете провайдера идентификации с помощью Google, это может помочь вам https://pub.dartlang.org/packages/google_sign_in
Для этого вы можете использовать эту библиотеку:
https://pub.dev/packages/googleapis_auth
Или вы можете использовать этот (как они рекомендуют):
https://pub.dev/packages/extension_google_sign_in_as_googleapis_auth
import "package:googleapis_auth/auth_io.dart";
// Use service account credentials to get an authenticated and auto refreshing client.
Future<AuthClient> obtainAuthenticatedClient() async {
final accountCredentials = ServiceAccountCredentials.fromJson({
"private_key_id": "<please fill in>",
"private_key": "<please fill in>",
"client_email": "<please fill in>@developer.gserviceaccount.com",
"client_id": "<please fill in>.apps.googleusercontent.com",
"type": "service_account"
});
var scopes = ["https://www.googleapis.com/auth/firebase.messaging"];
AuthClient client = await clientViaServiceAccount(accountCredentials, scopes);
return client; // Remember to close the client when you are finished with it.
}
Я создал этот класс, чтобы справиться с этим, используя рекомендуемую библиотеку.
class Messaging {
// region Singleton
static final Messaging _instance = Messaging._internal();
Messaging._internal();
static Messaging get instance => _instance;
//endregion
static final String projectId = '<your-project-id>';
static final String fcmUri =
'https://fcm.googleapis.com/v1/projects/$projectId/messages:send';
static final String messagingScope =
'https://www.googleapis.com/auth/firebase.messaging';
/// Credentials used to authenticate the http calls.
/// If it is null, at the first time, it will be created.
/// After that, we will check if the access token is valid.
/// If it is expired, we are going to refresh it.
/// We also need the client to refresh the token.
AccessCredentials? _credentials;
FirebaseMessaging get fcmInstance => FirebaseMessaging.instance;
/// Sends a message to a topic or specific device
/// [topic] might be a topic itself or a registered fcm token (the device token)
Future<String> sendMessage({
required String title,
required String message,
required String topic,
}) async {
Map<String, dynamic> notification = Map();
notification['title'] = title;
notification['body'] = message;
Map<String, dynamic> body = Map();
body["message"] = {
'topic': topic,
'notification': notification,
};
return _post(body);
}
/// Send data to the informed destionation
/// [data] must have a maximum 3kb
Future<String> sendData({
required String topic,
required Map<String, String> data,
}) async {
debugPrint('Send data to topic $topic: ');
Map<String, dynamic> body = Map();
body['message'] = {
'topic': topic,
'data': data,
};
return _post(body);
}
/// Posts the message
Future<String> _post(Map<String, dynamic> body) async {
Map<String, String> headers = await _buildHeaders();
return http
.post(
Uri.parse(fcmUri),
headers: headers,
body: json.encode(body),
)
.then((http.Response response) {
debugPrint(response.body);
return response.body;
});
}
/// Builds default header
Future<Map<String, String>> _buildHeaders() async {
await _autoRefreshCredentialsInitialize();
String token = _credentials!.accessToken.data;
Map<String, String> headers = Map();
headers["Authorization"] = 'Bearer $token';
headers["Content-Type"] = 'application/json';
return headers;
}
/// Use service account credentials to obtain oauth credentials.
/// Whenever new credentials are available, [_credentials] is updated automatically
Future<void> _autoRefreshCredentialsInitialize() async {
if (_credentials != null) {
return;
}
// [Assets.files.serviceAccount] is the path to the json created on Services Account
// Assets is a class that I created to access easily files on assets folder.
String source = await Assets.readString(Assets.files.serviceAccount);
final serviceAccount = jsonDecode(source);
var accountCredentials = ServiceAccountCredentials.fromJson(serviceAccount);
AutoRefreshingAuthClient autoRefreshingAuthClient =
await clientViaServiceAccount(
accountCredentials,
[messagingScope],
);
/// initialization
_credentials = autoRefreshingAuthClient.credentials;
// when new credetials are available, _credentials will be updated
// (it checks if the current credentials is expired)
autoRefreshingAuthClient.credentialUpdates.listen((credentials) {
_credentials = credentials;
});
}
//region Registered Token
Future<void> requestMessagingToken() async {
// Get the token each time the application loads
String? token = await fcmInstance.getToken();
// Save the initial token to the database
await _saveTokenToSharedPreference(token!);
// Any time the token refreshes, store this in the database too.
fcmInstance.onTokenRefresh.listen(_saveTokenToSharedPreference);
}
/// Verifica a necessidade de persistir o token
Future<void> _saveTokenToSharedPreference(String token) async {
FlutterSecureStorage prefs = FlutterSecureStorage();
// verifica se é igual ao anterior
String? prev = await prefs.read(key: 'tokenMessaging');
if (prev == token) {
debugPrint('Device registered!');
return;
}
try {
await prefs.write(key: "tokenMessaging", value: token);
debugPrint('Firebase token saved!');
} catch (e) {
FirebaseCrashlytics.instance.recordError(e, null);
print(e);
}
}
Future<String?> get firebaseToken {
FlutterSecureStorage prefs = FlutterSecureStorage();
return prefs.read(key: 'tokenMessaging');
}
//endregion
}