How to Update Your Profile from Dart/Flutter App using Bluesky API
Tags: dart, flutter, bluesky, api
Published: 2023-08-15 07:24:15

This article will show you how to update your profile from a Dart/Flutter application using the **Bluesky API**.

By reading this article, you will be able to easily update your Bluesky profile in your Dart/Flutter app from the Bluesky API.

## Using Package

To easily handle the Bluesky API in Dart/Flutter, use the following package.

- **[bluesky](https://pub.dev/packages/bluesky)**

{% embed https://pub.dev/packages/bluesky %}
{% embed https://github.com/myConsciousness/atproto.dart %}

If you want to learn more about **[bluesky](https://pub.dev/packages/bluesky)** package, see following **[official website](https://atprotodart.com)**.

{% embed https://atprotodart.com %}

## Install

Let's install **[bluesky](https://pub.dev/packages/bluesky)** with the following commands.

**With Dart:**

```bash
dart pub add bluesky
```

```dash
dart pub get
```

**With Flutter:**

```bash
flutter pub add bluesky
```

```dash
flutter pub get
```

## Import

Basically, when you use features of the **[bluesky](https://pub.dev/packages/bluesky)** package, just add the following import.

```dart
import 'package:bluesky/bluesky.dart';
```

## Implement

We will implement, but let's start with a very simple step. The following example shows the process for updating the `displayName` and `description` of an authenticated user.

> In order to update a Bluesky profile, you must of course be authorized to update the information for the account you are updating, so be sure to authenticate using the `createSession` function. You can see more details about authentication on **[official document](https://atprotodart.com/docs/packages/bluesky#instantiate-bluesky)**.

```dart
import 'package:bluesky/bluesky.dart' as bsky;

Future<void> main() async {
  final session = await bsky.createSession(
    identifier: 'HANDLE_OR_EMAIL',
    password: 'PASSWORD',
  );

  final bluesky = bsky.Bluesky.fromSession(session.data);

  final ref = await bluesky.actors.updateProfile(
    displayName: 'Alf',
    description: 'This is my new profile.',
  );

  print(ref.data);
}
```

As shown in the code above, to update the Bluesky profile of an authenticated user using the **[bluesky](https://pub.dev/packages/bluesky)** package, use the **[`.updateProfile`](https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html)** method of the **[ActorsService](https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService-class.html)**.

So, all you have to do to update your Bluesky profile using the **[bluesky](https://pub.dev/packages/bluesky)** package is call the **[`.updateProfile`](https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html)** method.

The above example only updates the `displayName` and `description`, but the following items can be updated.

|Parameter|Description|
|---|---|
| **displayName** |A logical name for the profile. |
| **descriotion** |A description of the account that will be set up in the profile. |
| **avatar** |An image that symbolizes the account that is set in the profile. |
| **banner** |A banner image to be set in the profile. |
| **labels** |An optional tag set for the account.|

Setting up a profile picture and label is a bit more difficult than setting up a `displayName` or `description`, so we will look at that in the next section.

## Update Avatar and Banner

To update your `avatar` or `banner`, you must first upload the binary data of the image you wish to set to the server. To upload binary data of images to the server, implement the following. 

```dart
import 'dart:io';

import 'package:bluesky/bluesky.dart' as bsky;

Future<void> main() async {
  final session = await bsky.createSession(
    identifier: 'HANDLE_OR_EMAIL',
    password: 'PASSWORD',
  );

  final bluesky = bsky.Bluesky.fromSession(session.data);

  // Get image file to be uploaded.
  final image = File('./funny_photo.png');

  // Upload here.
  final uploaded = await bluesky.repositories.uploadBlob(
    image.readAsBytesSync(),
  );
}
```

As shown in the code above, the **[`.uploadBlob`](https://pub.dev/documentation/bluesky/latest/bluesky/RepositoriesService/uploadBlob.html)** method of the **[RepositoriesService](https://pub.dev/documentation/bluesky/latest/bluesky/RepositoriesService-class.html)** is used to upload the binary data. 

> Bluesky Social only supports static images at the time of this writing, but the AT Protocol allows for the upload of binary data in any format.

After a successful upload, you will get a **[`Blob`](https://pub.dev/documentation/bluesky/latest/bluesky/Blob-class.html)** object to pass to the `avatar` parameter when updating your profile image. All that remains is to pass a **[`Blob`](https://pub.dev/documentation/bluesky/latest/bluesky/Blob-class.html)** object to the `avatar` parameter as follows.

```dart
import 'dart:io';

import 'package:bluesky/bluesky.dart' as bsky;

Future<void> main() async {
  final session = await bsky.createSession(
    identifier: 'HANDLE_OR_EMAIL',
    password: 'PASSWORD',
  );

  final bluesky = bsky.Bluesky.fromSession(session.data);

  final image = File('./funny_photo.png');

  final uploaded = await bluesky.repositories.uploadBlob(
    image.readAsBytesSync(),
  );

  final ref = await bluesky.actors.updateProfile(
    displayName: 'Alf',
    description: 'This is my new profile.',

    // Pass like this.
    avatar: uploaded.data.blob,
  );

  print(ref.data);
}
```

The `banner` parameter can also be implemented in exactly the same way as above.

## Set Labels

You can set any tags, called a **label**, to your profile in Bluesky. It is up to you to decide what kind of tags you want to set in your profile, and you can set any string of characters.

And setting up a label for your profile is easier than uploading an image. It can be implemented as follows.

```dart
import 'package:bluesky/bluesky.dart' as bsky;

Future<void> main() async {
  final session = await bsky.createSession(
    identifier: 'HANDLE_OR_EMAIL',
    password: 'PASSWORD',
  );

  final bluesky = bsky.Bluesky.fromSession(session.data);

  final ref = await bluesky.actors.updateProfile(
    displayName: 'Alf',
    description: 'This is my new profile.',

    // Add like this.
    labels: bsky.Labels.selfLabels(
      data: bsky.SelfLabels(
        values: [
          bsky.SelfLabel(value: 'developer'),
          bsky.SelfLabel(value: 'flutterdev'),
        ],
      ),
    ),
  );

  print(ref.data);
}
```

The structure of the objects passed to the `labels` parameter is somewhat complex, but not as laborious as the upload process. As you can see in the code above, you can set any number of strings as labels.

But well, let's make the implementation just a little more generic.

```dart
import 'package:bluesky/bluesky.dart' as bsky;

/// Labels to be set.
const _labels = <String>[
  'developer',
  'flutterdev',
];

Future<void> main() async {
  final session = await bsky.createSession(
    identifier: 'HANDLE_OR_EMAIL',
    password: 'PASSWORD',
  );

  final bluesky = bsky.Bluesky.fromSession(session.data);

  final ref = await bluesky.actors.updateProfile(
    displayName: 'Alf',
    description: 'This is my new profile.',

    labels: bsky.Labels.selfLabels(
      data: bsky.SelfLabels(
        // Fix like this.
        values: _labels.map((e) => bsky.SelfLabel(value: e)).toList(),
      ),
    ),
  );

  print(ref.data);
}
```

## Advanced

So far you have learned how to update your Bluesky profile using the **[bluesky](https://pub.dev/packages/bluesky)** package, but there is one more thing to consider in order to actually use the **[`.updateProfile`](https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html)** method in your Dart/ Flutter app.

Although it is not explicitly shown even in the [official Lexicon](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/actor/profile.json), a parameter set as `null` using the **[`.updateProfile`](https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html)** method sets the authenticated user's profile data as `null`. In other words, if you try to update only a specific item and pass the other parameters as `null`, the profile data for the item associated with the parameter passed as `null` will be deleted.

So, you must **_always_** pass specific values to **[`.updateProfile`](https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html)** for parameters other than the item to be deleted, unless the user explicitly takes action to delete a specific item.

**But**, the problem here is that it is somewhat difficult to find a way to retrieve the uploaded `avatar` and `banner` binary data again. You can implement it as follows.

```dart
import 'package:bluesky/bluesky.dart' as bsky;

Future<void> main() async {
  final session = await bsky.createSession(
    identifier: 'HANDLE_OR_EMAIL',
    password: 'PASSWORD',
  );

  final bluesky = bsky.Bluesky.fromSession(session.data);

  // The AT Uri for authenticated user's profile.
  // The format can be used as is.
  final profileUri = bsky.AtUri.make(
    session.data.did,
    'app.bsky.actor.profile',
    'self',
  );

  // Get profile record.
  final record = await bluesky.repositories.findRecord(uri: profileUri);
  // And parse value to `ProfileRecord`.
  final profileRecord = bsky.ProfileRecord.fromJson(record.data.value);

  // Very safe update.
  // Replace the item you wish to update with a specific variable.
  final ref = await bluesky.actors.updateProfile(
    displayName: profileRecord.displayName,
    description: profileRecord.description,
    avatar: profileRecord.avatar,
    banner: profileRecord.banner,
    labels: profileRecord.labels,
  );

  print(ref.data);
}
```

Using the above code as a base, you can update your profile very safely. 

## Conclusion

Now that you have somewhat understood how to update your Bluesky profile from the Dart/Flutter app using the **[bluesky](https://pub.dev/packages/bluesky)** package, you can use it to update your Bluesky profile from the Dart/Flutter app. You have also learned that updating your profile using the Bluesky API may seem easy, but in reality it requires some technique.

If you are still not sure how to implement it after reading this article, please mention me at Bluesky.

- **[@shinyakato.dev](https://bsky.app/profile/shinyakato.dev)**

Also, if you found this article useful, please star the following repositories where **[bluesky](https://pub.dev/packages/bluesky)** package are developed. This is very helpful to activate the development community.

![github_star](https://github.com/myConsciousness/atproto.dart/assets/13072231/c4a9b0b9-6ea4-42f1-823b-3b9e7cdb8b04)

{% embed https://github.com/myConsciousness/atproto.dart %}

Thank you.