// Here's a channel with some custom field data that might be useful val channelClient = client.channel(channelType = "messaging", channelId = "general") channelClient.create( memberIds = listOf("thierry", "tomasso"), extraData = mapOf( "source" to "user", "source_detail" to mapOf("user_id" to 123), "channel_detail" to mapOf( "topic" to "Plants and Animals", "rating" to "pg" ) ) ).execute() // let's change the source of this channel channelClient.updatePartial(set = mapOf("source" to "system")).execute() // since it's system generated we no longer need source_detail channelClient.updatePartial(unset = listOf("source_detail")).execute() // and finally update one of the nested fields in the channel_detail channelClient.updatePartial(set = mapOf("channel_detail.topic" to "Nature")).execute() // and maybe we decide we no longer need a rating channelClient.updatePartial(unset = listOf("channel_detail.rating")).execute()Updating a Channel
There are two ways to update a channel with the Stream API: partial updates and full updates. A partial update preserves existing custom key–value data, while a full update replaces the entire channel object and removes any fields not included in the request.
Partial Update
A partial update lets you set or unset specific fields without affecting the rest of the channel’s custom data — essentially a patch-style update.
// Here's a channel with some custom field data that might be useful const channel = client.channel(type, id, { source: "user", source_detail: { user_id: 123 }, channel_detail: { topic: "Plants and Animals", rating: "pg" }, }); // let's change the source of this channel await channel.updatePartial({ set: { source: "system" } }); // since it's system generated we no longer need source_detail await channel.updatePartial({ unset: ["source_detail"] }); // and finally update one of the nested fields in the channel_detail await channel.updatePartial({ set: { "channel_detail.topic": "Nature" } }); // and maybe we decide we no longer need a rating await channel.updatePartial({ unset: ["channel_detail.rating"] });// Here's a channel with some custom field data that might be useful var channel = client.channel(type, id: id, extraData: { "source": "user", "source_detail" :{ "user_id": 123 }, "channel_detail" :{ "topic": "Plants and Animals", "rating": "pg" } }); // let's change the source of this channel await channel.updatePartial(set: { "source": "system" }); // since it's system generated we no longer need source_detail await channel.updatePartial(unset: ["source_detail"]); // and finally update one of the nested fields in the channel_detail await channel.updatePartial(set: { "channel_detail.topic": "Nature" }); // and maybe we decide we no longer need a rating await channel.updatePartial(unset: ["channel_detail.rating"]);# Here's a channel with some custom field data that might be useful channel = client.channel(type, id , { "source": "user", "source_detail":{ "user_id": 123 }, "channel_detail":{ "topic": "Plants and Animals", "rating": "pg" } }) # let's change the source of this channel channel.update_partial(to_set={ "source": "system" }); # since it's system generated we no longer need source_detail channel.update_partial(to_unset=["source_detail"]); # and finally update one of the nested fields in the channel_detail channel.update_partial(to_set={ "channel_detail.topic": "Nature" }); # and maybe we decide we no longer need a rating channel.update_partial(to_unset=["channel_detail.rating"]);// Here's a channel with some custom field data that might be useful $channel = $client->Channel('messaging', 'thierry-jenny', ['source'=>'user','source_detail'=>['user_id'=>123], 'channel_detail'=>['topic'=>'Plants and Animals', 'rating'=> 'pg'] ]); // let's change the source of this channel $response = $channel->updatePartial(['source' => 'system']); // since it's system generated we no longer need source_detail $response = $channel->updatePartial(null,['source_detail']); // and finally update one of the nested fields in the channel_detail $response = $channel->updatePartial(['source_detail'=> ['topic' => 'Nature']]); // and maybe we decide we no longer need a rating $response = $channel->updatePartial(null,['source_detail'=>'topic']);// Create a channel with some custom data var req = new ChannelGetRequest { Data = new ChannelRequest { CreatedBy = new UserRequest { Id = createdByUserId }, }, }; req.Data.SetData("source", "user"); req.Data.SetData("source_detail", new Dictionary<string, object> { { "user_id", 123} }); req.Data.SetData("channel_detail", new Dictionary<string, object> { { "topic", "Plants and Animals"}, { "rating", "pg" } }); var channelResp = await channelClient.GetOrCreateAsync("messaging", "general", req); // Remove channel detail rating, and set a new source var req = new PartialUpdateChannelRequest { Unset = new List<string> { "channel_detail.rating" }, Set = new Dictionary<string, object> { { "source", "system" } } }; await channelClient.PartialUpdateAsync(channelResp.Channel.Type, channelResp.Channel.Id, req);// Create a channel with some custom field data that might be useful FChannelProperties Props = FChannelProperties{Type, Id}; // Set extra data using dynamic JSON. You'd more likely want to use statically typed structs. Props.ExtraData.SetString(TEXT("source"), TEXT("user")); const TSharedRef<FJsonObject> SourceDetail = MakeShared<FJsonObject>(); SourceDetail->SetNumberField(TEXT("user_id"), 123); Props.ExtraData.SetJsonValue(TEXT("source_detail"), MakeShared<FJsonValueObject>(SourceDetail)); const TSharedRef<FJsonObject> ChannelDetail = MakeShared<FJsonObject>(); ChannelDetail->SetStringField(TEXT("topic"), TEXT("Plants and Animals")); ChannelDetail->SetStringField(TEXT("rating"), TEXT("pg")); Props.ExtraData.SetJsonValue(TEXT("source_detail"), MakeShared<FJsonValueObject>(ChannelDetail)); Client->CreateChannel( Props, [](UChatChannel* Channel) { // let's change the source of this channel const TSharedRef<FJsonObject> NewSource = MakeShared<FJsonObject>(); NewSource->SetStringField(TEXT("source"), TEXT("system")); Channel->PartialUpdate(NewSource); // since it's system generated we no longer need source_detail Channel->PartialUpdate({}, {TEXT("source_detail")}); // and finally update one of the nested fields in the channel_detail const TSharedRef<FJsonObject> NewTopic = MakeShared<FJsonObject>(); NewSource->SetStringField(TEXT("channel_detail.topic"), TEXT("Nature")); Channel->PartialUpdate(NewSource); // and maybe we decide we no longer need a rating Channel->PartialUpdate({}, {TEXT("channel_detail.rating")}); });resp, err := c.CreateChannel(ctx, "messaging", "general", "thierry", map[string]interface{}{ "source": "user", "source_detail": map[string]interface{}{"user_id": "123"}, "channel_detail": map[string]interface{}{"topic": "Plants and Animals", "rating": "pg"}, }) channel := resp.Channel // let's change the source of this channel channel.PartialUpdate(ctx, PartialUpdate{ Set: map[string]interface{}{ "source": "system", }, }) // since it's system generated we no longer need source_detail channel.PartialUpdate(ctx, PartialUpdate{ Unset: []string{"source_detail"}, }) // and finally update one of the nested fields in the channel_detail channel.PartialUpdate(ctx, PartialUpdate{ Set: map[string]interface{}{ "channel_detail.topic": "Nature", }, }) // and maybe we decide we no longer need a rating channel.PartialUpdate(ctx, PartialUpdate{ Unset: []string{"channel_detail.rating"}, })# require 'stream-chat' # Here's a channel with some custom field data that might be useful channel = client.channel(type, id , data: { "source" => "user", "source_detail" => { "user_id" => 123 }, "channel_detail" => { "topic" => "Plants and Animals", "rating" => "pg" } }) # let's change the source of this channel channel.update_partial({ "source" => "system" }); # since it's system generated we no longer need source_detail channel.update_partial(nil, ["source_detail"]); # and finally update one of the nested fields in the channel_detail channel.update_partial({ "channel_detail.topic" => "Nature" }); # and maybe we decide we no longer need a rating channel.update_partial(nil, ["channel_detail.rating"]);public async Task PartialUpdate() { var channel = await Client.GetOrCreateChannelWithIdAsync(ChannelType.Messaging, channelId: "my-channel-id"); var setClanInfo = new ClanData { MaxMembers = 50, Name = "Wild Boards", Tags = new List<string> { "Competitive", "Legendary", } }; var setFields = new Dictionary<string, object>(); // Set custom values setFields.Add("frags", 5); // Set custom arrays setFields.Add("items", new[] { "sword", "shield" }); // Set custom class objects setFields.Add("clan_info", setClanInfo); // Send data await channel.UpdatePartialAsync(setFields); // Data is now available via CustomData property var frags = channel.CustomData.Get<int>("frags"); var items = channel.CustomData.Get<List<string>>("items"); var clanInfo = channel.CustomData.Get<ClanData>("clan_info"); } // Example class with data that you can assign as Channel custom data private class ClanData { public int MaxMembers; public string Name; public List<string> Tags; }// Android SDK // Here's a channel with some custom field data that might be useful ChannelClient channelClient = client.channel("messaging", "general"); List<String> members = Arrays.asList("thierry", "tommaso"); Map<String, String> channelDetail = new HashMap<>(); channelDetail.put("topic", "Plants and Animals"); channelDetail.put("rating", "pg"); Map<String, Integer> userId = new HashMap<>(); userId.put("user_id", 123); Map<String, Object> extraData = new HashMap<>(); extraData.put("source", "user"); extraData.put("source_detail", userId); extraData.put("channel_detail", channelDetail); channelClient.create(members, extraData).execute(); // let's change the source of this channel Map<String, Object> setField = Collections.singletonMap("source", "system"); channelClient.updatePartial(setField, emptyList()).execute(); // since it's system generated we no longer need source_detail List<String> unsetField = Collections.singletonList("source_detail"); channelClient.updatePartial(emptyMap(), unsetField).execute(); // and finally update one of the nested fields in the channel_detail Map<String, Object> setNestedField = Collections.singletonMap("channel_detail.topic", "Nature"); channelClient.updatePartial(setNestedField, emptyList()).execute(); // and maybe we decide we no longer need a rating List<String> unsetNestedField = Collections.singletonList("channel_detail.rating"); channelClient.updatePartial(emptyMap(), unsetNestedField).execute(); // Backend SDK Channel.partialUpdate("messaging", "general") .setValue("source", "system") .setValue("channel_detail.topic", "Nature") .user(user) .unsetValue("source_detail") .request() .getChannel();channelController.partialChannelUpdate( extraData: [ "source": .string("user"), "source_detail": .dictionary(["user_id": .number(123)]), "channel_detail": .dictionary([ "topic": .string("Plants and Animals"), "rating": .string("pg") ]) ] ) { error in if let error { // handle error } } // let's change the source of this channel channelController.partialChannelUpdate(unsetProperties: ["source_detail"]) // let's change the source of this channel channelController.partialChannelUpdate(extraData:["source": "system"]) // since it's system generated we no longer need source_detail channelController.partialChannelUpdate(unsetProperties: ["source_detail"]) // and finally update one of the nested fields in the channel_detail channelController.partialChannelUpdate(extraData:["channel_detail.topic": "Nature"])Full Update
The update function updates all of the channel data. Any data that is present on the channel and not included in a full update will be deleted.
val channelClient = client.channel("messaging", "general") channelClient.update( message = Message( text = "Thierry changed the channel color to green" ), extraData = mapOf( "name" to "myspecialchannel", "color" to "green", ), ).enqueue { result -> if (result is Result.Success) { val channel = result.value } else { // Handle Result.Failure } }const update = await channel.update({ name: "myspecialchannel", color: "green", });await channel.update({ "name": "myspecialchannel", "color": "green", }, Message(text: "Thierry changed the channel color to green"));$update = $channel->update( [ 'name' => 'myspecialchannel', 'color' => 'green' ], [ 'text' => 'Thierry changed the channel color to green', 'user_id' => 'thierry' ] );let channelController = chatClient.channelController(for: .init(type: .messaging, id: "general")) channelController.updateChannel( name: "My special channel", imageURL: nil, team: nil, extraData: [ "name": .string("myspecialchannel"), "color": .string("green"), ] ) { error in if let error { // handle error } }channel.update( { "name": "myspecialchannel", "color": "green", }, )FAdditionalFields Data; Data.SetString(TEXT("name"), TEXT("myspecialchannel")); Data.SetString(TEXT("color"), TEXT("green")); Channel->Update(Data, Message);var updatedChannel = new ChannelUpdateRequest { Data = new ChannelRequest() }; updatedChannel.Data.SetData("name", "myspecialchannel"); updatedChannel.Data.SetData("color", "green"); await channelClient.UpdateAsync(channel.Type, channel.Id, updatedChannel);channel.Update(ctx, map[string]interface{}{"color": "green"},)channel.update( { "name" => "myspecialchannel", "color" => "green", }, )var updateRequest = new StreamUpdateOverwriteChannelRequest { Name = "New name", CustomData = new StreamCustomDataRequest { {"my-custom-int", 12}, {"my-custom-array", new string[]{"one", "two"}} } }; // This request will have all channel data removed except what is being passed in the request await channel.UpdateOverwriteAsync(updateRequest); // You can also pass an instance of channel to the request constructor to have all of the date copied over // This way you alter only the fields you wish to change var updateRequest2 = new StreamUpdateOverwriteChannelRequest(channel) { Name = "Brand new name" }; // This will update only the name because all other data was copied over await channel.UpdateOverwriteAsync(updateRequest2);// Android SDK ChannelClient channelClient = client.channel("messaging", "general"); Map<String, Object> channelData = new HashMap<>(); channelData.put("name", "myspecialchannel"); channelData.put("color", "green"); Message updateMessage = new Message(); updateMessage.setText("Thierry changed the channel color to green"); channelClient.update(updateMessage, channelData).enqueue(result -> { if (result.isSuccess()) { Channel channel = result.data(); } else { // Handle result.error() } }); // Backend SDK MessageRequestObject msg = MessageRequestObject .builder() .text("Thierry changed the channel color to green") .build(); Channel.update("messaging", "general") .message(msg) .data(ChannelRequestObject.builder() .additionalField("name", "myspecialchannel") .additionalField("color", "green") .build()) .request();Request Params
| Name | Type | Description | Optional |
|---|---|---|---|
| channel data | object | Object with the new channel information. One special field is “frozen”. Setting this field to true will freeze the channel. Read more about freezing channels in “Freezing Channels” | |
| text | object | Message object allowing you to show a system message in the Channel that something changed. | Yes |
Updating a channel using these methods cannot be used to add or remove members. For this, you must use specific methods for adding/removing members, more information can be found here.
Adding & Removing Channel Filter Tags
Using the addFilterTags() method adds tags to categorize a channel, while removeFilterTags() removes them.
const channel = client.channel("messaging", "support-123"); // Add filter tags await channel.addFilterTags(["premium", "urgent"]); // Remove filter tags await channel.removeFilterTags(["urgent"]);channel := client.Channel("messaging", "support-123") // Add filter tags _, err := channel.AddFilterTags(ctx, []string{"premium", "urgent"}) // Remove filter tags _, err = channel.RemoveFilterTags(ctx, []string{"urgent"})channel = client.channel("messaging", "support-123") # Add filter tags channel.add_filter_tags(["premium", "urgent"]) # Remove filter tags channel.remove_filter_tags(["urgent"])$channel = $client->Channel("messaging", "support-123"); // Add filter tags $channel->addFilterTags(['premium', 'urgent']); // Remove filter tags $channel->removeFilterTags(['urgent']);channel = client.channel("messaging", "support-123") # Add filter tags channel.add_filter_tags(["premium", "urgent"]) # Remove filter tags channel.remove_filter_tags(["urgent"])// Add filter tags await channelClient.AddFilterTagsAsync("messaging", "support-123", new[] { "premium", "urgent" }); // Remove filter tags await channelClient.RemoveFilterTagsAsync("messaging", "support-123", new[] { "urgent" });// Backend SDK Channel.update("messaging", "support-123") .addFilterTags(Arrays.asList("premium", "urgent")) .request(); Channel.update("messaging", "support-123") .removeFilterTags(Arrays.asList("urgent")) .request();Limits: A channel can have a maximum of 10 tags total. Each tag is limited to 255 characters. Tags are automatically sorted and deduplicated by the system.
Filter tags can also be set when creating the channel. See Creating Channels for more details, and Querying Channels for filtering channels by tags.